diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..3e297c0 --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +sub-package.* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 323b644..72cb932 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,927 +1,1208 @@ -# Changelog -All notable changes to this package will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [10.2.2] - 2020-12-07 - -Version Updated -The version number for this package has increased due to a version update of a related graphics package. - -## [10.2.1] - 2020-11-30 - -Version Updated -The version number for this package has increased due to a version update of a related graphics package. - -## [10.2.0] - 2020-10-19 - -### Added -- Added a supported MSAA samples count check, so the actual supported MSAA samples count value can be assigned to RenderTexture descriptors. - -### Changed -- Changed RenderObjectsFeature UI to only expose valid events. Previously, when selecting events before BeforeRenderingPrepasses objects would not be drawn correctly as stereo and camera setup only happens before rendering opaques objects. -- Shader functions SampleSH9, SampleSHPixel, SampleSHVertex are now gamma corrected in gamma space. As result LightProbes are gamma corrected too. -- Bloom in Gamma color-space now more closely matches Linear color-space, this will mean project using Bloom and Gamma color-space may need to adjust Bloom Intensity to match previous look. - -### Fixed -- Fixed the Unlit shader not being SRP Batcher compatible on OpenGLES/OpenGLCore. [case 1263720](https://issuetracker.unity3d.com/issues/urp-mobile-srp-batcher-is-not-visible-on-mobile-devices-in-frame-debugger) -- Fixed an issue with soft particles not rendering correctly for overlay cameras with post processing. [case 1241626](https://issuetracker.unity3d.com/issues/soft-particles-does-not-fade-out-near-the-opaque-surfaces-when-post-processing-is-enabled-on-a-stacked-camera) -- Removed the warning about mis-matched vertex streams when creating a default Particle System. [case 1285272](https://issuetracker.unity3d.com/issues/particles-urp-default-material-shows-warning-in-inspector) -- Fixed latest mockHMD renderviewport scale doesn't fill whole view after scaling. [case 1286161] (https://issuetracker.unity3d.com/issues/xr-urp-renderviewportscale-doesnt-fill-whole-view-after-scaling) -- Fixed camera renders black in XR when user sets invalid MSAA value. -- Fixed an issue causing additional lights to stop working when set as the sun source. [case 1278768](https://issuetracker.unity3d.com/issues/urp-every-light-type-is-rendered-as-directional-light-if-it-is-set-as-sun-source-of-the-environment) -- Fixed an issue that caused a null reference when Lift Gamma Gain was being displayed in the Inspector and URP was upgraded to a newer version. [case 1283588](https://issuetracker.unity3d.com/issues/argumentnullexception-is-thrown-when-upgrading-urp-package-and-volume-with-lift-gamma-gain-is-focused-in-inspector) -- Fixed an issue where soft particles were not rendered when depth texture was disabled in the URP Asset. [case 1162556](https://issuetracker.unity3d.com/issues/lwrp-unlit-particles-shader-is-not-rendered-when-soft-particles-are-enabled-on-built-application) -- Fixed an issue where soft particles were rendered opaque on OpenGL. [case 1226288](https://issuetracker.unity3d.com/issues/urp-objects-that-are-using-soft-particles-are-rendered-opaque-when-opengl-is-used) -- Fixed an issue where the depth texture sample node used an incorrect texture in some frames. [case 1268079](https://issuetracker.unity3d.com/issues/urp-depth-texture-sample-node-does-not-use-correct-texture-in-some-frames) -- Fixed MSAA on Metal MacOS and Editor. -- Fixed an issue causing passthrough camera to not render. [case 1283894](https://issuetracker.unity3d.com/product/unity/issues/guid/1283894/) -- Fixed MSAA override on camera does not work in non-XR project if target eye is selected to both eye. -- Fixed a compiler error in BakedLit shader when using Hybrid Renderer. -- Fixed XR camera fov can be changed through camera inspector. -- Fixed LightProbes to have gamma correct when using gamma color space. [case 1268911](https://issuetracker.unity3d.com/issues/urp-has-no-gamma-correction-for-lightprobes) -- Fixed an issue causing materials to be upgraded multiple times. -- Fixed an issue where the Camera inspector was grabbing the URP asset in Graphics Settings rather than the currently active. -- Fixed an issue where the Light Explorer was grabbing the URP asset in Graphics Settings rather than the currently active. -- Fixed an issue where the scene view camera ignored the pipeline assets HDR setting. [case 1284369](https://issuetracker.unity3d.com/issues/urp-scene-view-camera-ignores-pipeline-assets-hdr-settings-when-main-camera-uses-pipeline-settings) -- Fixed bloom inconsistencies between Gamma and Linear color-spaces. -- Fixed an issue with upgrading material set to cutout didn't properly set alpha clipping. [case 1235516](https://issuetracker.unity3d.com/issues/urp-upgrade-material-utility-does-not-set-the-alpha-clipping-when-material-was-using-a-shader-with-rendering-mode-set-to-cutout) - -## [10.1.0] - 2020-10-12 -### Added -- Added support for the Shadowmask Mixed Lighting Mode (Forward only), which supports up to four baked-shadow Lights. -- Added ComplexLit shader for advanced material features and deferred forward fallback. -- Added Clear Coat feature for ComplexLit shader and for shader graph. -- Added Parallax Mapping to the Lit shader (Lit.shader). -- Added the Detail Inputs setting group in the Lit shader (Lit.shader). -- Added Smooth shadow fading. -- The pipeline now outputs a warning in the console when trying to access camera color or depth texture when those are not valid. Those textures are only available in the context of `ScriptableRenderPass`. -- Added a property to access the renderer from the `CameraData`. - -### Changed -- The maximum number of visible lights when using OpenGL ES 3.x on Android now depends on the minimum OpenGL ES 3.x version as configured in PlayerSettings. -- The default value of the HDR property of a newly created Universal Render Pipeline Asset, is now set to true. - -### Fixed -- Fixed an issue where the CapturePass would not capture the post processing effects. -- Fixed an issue were the filter window could not be defocused using the mouse. [case 1242032](https://issuetracker.unity3d.com/issues/urp-volume-override-window-doesnt-disappear-when-clicked-on-the-other-windows-in-the-editor) -- Fixed camera backgrounds not matching between editor and build when background is set to 'Uninitialized'. [case 1224369](https://issuetracker.unity3d.com/issues/urp-uninitialized-camera-background-type-does-not-match-between-the-build-and-game-view) -- Fixed a case where main light hard shadows would not work if any other light is present with soft shadows.[case 1250829](https://issuetracker.unity3d.com/issues/main-light-shadows-are-ignored-in-favor-of-additional-lights-shadows) -- Fixed issue that caused color grading to not work correctly with camera stacking. [case 1263193](https://issuetracker.unity3d.com/product/unity/issues/guid/1263193/) -- Fixed an issue that caused an infinite asset database reimport when running Unity in command line with -testResults argument. -- Fixed ParticlesUnlit shader to use fog color instead of always black. [case 1264585] -- Fixed issue that caused some properties in the camera to not be bolded and highlighted when edited in prefab mode. [case 1230082](https://issuetracker.unity3d.com/issues/urp-camera-prefab-fields-render-type-renderer-background-type-are-not-bolded-and-highlighted-when-edited-in-prefab-mode) -- Fixed issue where blur would sometimes flicker [case 1224915](https://issuetracker.unity3d.com/issues/urp-bloom-effect-flickers-when-using-integrated-post-processing-feature-set) -- Fixed an issue in where the camera inspector didn't refresh properly when changing pipeline in graphic settings. [case 1222668](https://issuetracker.unity3d.com/issues/urp-camera-properties-not-refreshing-on-adding-or-removing-urp-pipeline-in-the-graphics-setting) -- Fixed depth of field to work with dynamic resolution. [case 1225467](https://issuetracker.unity3d.com/issues/dynamic-resolution-rendering-error-when-using-depth-of-field-in-urp) -- Fixed FXAA, SSAO, Motion Blur to work with dynamic resolution. -- Fixed an issue where Pixel lighting variants were stripped in builds if another URP asset had Additional Lights set to Per Vertex [case 1263514](https://issuetracker.unity3d.com/issues/urp-all-pixel-lighting-variants-are-stripped-in-build-if-at-least-one-urp-asset-has-additional-lights-set-to-per-vertex) -- Fixed an issue where transparent meshes were rendered opaque when using custom render passes [case 1262887](https://issuetracker.unity3d.com/issues/urp-transparent-meshes-are-rendered-as-opaques-when-using-lit-shader-with-custom-render-pass) -- Fixed regression from 8.x.x that increased launch times on Android with GLES3. [case 1269119](https://issuetracker.unity3d.com/issues/android-launch-times-increased-x4-from-urp-8-dot-1-0-to-urp-10-dot-0-0-preview-dot-26) -- Fixed an issue with a render texture failing assertion when chosing an invalid format. [case 1222676](https://issuetracker.unity3d.com/issues/the-error-occurs-when-a-render-texture-which-has-a-certain-color-format-is-applied-to-the-cameras-output-target) -- Fixed an issue that caused the unity_CameraToWorld matrix to have z flipped values. [case 1257518](https://issuetracker.unity3d.com/issues/parameter-unity-cameratoworld-dot-13-23-33-is-inverted-when-using-universal-rp-7-dot-4-1-and-newer) -- Fixed not using the local skybox on the camera game object when the Skybox Material property in the Lighting window was set to null. -- Fixed an issue where, if URP was not in use, you would sometimes get errors about 2D Lights when going through the menus. -- Fixed GC when using XR single-pass automated tests. -- Fixed an issue that caused a null reference when deleting camera component in a prefab. [case 1244430](https://issuetracker.unity3d.com/issues/urp-argumentnullexception-error-is-thrown-on-removing-camera-component-from-camera-prefab) -- Fixed resolution of intermediate textures when rendering to part of a render texture. [case 1261287](https://issuetracker.unity3d.com/product/unity/issues/guid/1261287/) -- Fixed indirect albedo not working with shadergraph shaders in some rare setups. [case 1274967](https://issuetracker.unity3d.com/issues/gameobjects-with-custom-mesh-are-not-reflecting-the-light-when-using-the-shader-graph-shaders) -- Fixed XR mirroView sRGB issue when color space is gamma. -- Fixed an issue where XR eye textures are recreated multiple times per frame due to per camera MSAA change. -- Fixed an issue wehre XR mirror view selector stuck. -- Fixed GLES2 shader compilation. -- Fixed issue with lens distortion breaking rendering when enabled and its intensity is 0. -- Fixed issue that caused motion blur to not work in XR. -- Fixed issue where multiple cameras would cause GC each frame. [case 1259717](https://issuetracker.unity3d.com/issues/urp-scriptablerendercontext-dot-getcamera-array-dot-resize-creates-garbage-every-frame-when-more-than-one-camera-is-active) -- Fixed Missing camera cannot be removed after scene is saved by removing the Missing camera label. [case 1252255](https://issuetracker.unity3d.com/issues/universal-rp-missing-camera-cannot-be-removed-from-camera-stack-after-scene-is-saved) -- Fixed MissingReferenceException when removing Missing camera from camera stack by removing Missing camera label. [case 1252263](https://issuetracker.unity3d.com/issues/universal-rp-missingreferenceexception-errors-when-removing-missing-camera-from-stack) -- Fixed slow down in the editor when editing properties in the UI for renderer features. [case 1279804](https://issuetracker.unity3d.com/issues/a-short-freeze-occurs-in-the-editor-when-expanding-or-collapsing-with-the-arrow-the-renderer-feature-in-the-forward-renderer) - -## [10.0.0] - 2020-06-10 -### Added -- Added the option to strip Terrain hole Shader variants. -- Added support for additional Directional Lights. The amount of additional Directional Lights is limited by the maximum Per-object Lights in the Render Pipeline Asset. -- Added default implementations of OnPreprocessMaterialDescription for FBX, Obj, Sketchup and 3DS file formats. -- Added Transparency Sort Mode and Transparency Sort Axis to 2DRendererData. -- Added support for a user defined default material to 2DRendererData. -- Added the option to toggle shadow receiving on transparent objects. -- Added XR multipass rendering. Multipass rendering is a requirement on many VR platforms and allows graceful fallback when single-pass rendering isn't available. -- Added support for Camera Stacking when using the Forward Renderer. This introduces the Camera `Render Type` property. A Base Camera can be initialized with either the Skybox or Solid Color, and can combine its output with that of one or more Overlay Cameras. An Overlay Camera is always initialized with the contents of the previous Camera that rendered in the Camera Stack. -- Added AssetPostprocessors and Shadergraphs to handle Arnold Standard Surface and 3DsMax Physical material import from FBX. -- Added `[MainTexture]` and `[MainColor]` shader property attributes to URP shader properties. These will link script material.mainTextureOffset and material.color to `_BaseMap` and `_BaseColor` shader properties. -- Added the option to specify the maximum number of visible lights. If you set a value, lights are sorted based on their distance from the Camera. -- Added the option to control the transparent layer separately in the Forward Renderer. -- Added the ability to set individual RendererFeatures to be active or not, use `ScriptableRendererFeature.SetActive(bool)` to set whether a Renderer Feature will execute, `ScriptableRendererFeature.isActive` can be used to check the current active state of the Renderer Feature. - additional steps to the 2D Renderer setup page for quality and platform settings. -- If Unity Editor Analytics are enabled, Universal collects anonymous data about usage of Universal. This helps the Universal team focus our efforts on the most common scenarios, and better understand the needs of our customers. -- Added a OnCameraSetup() function to the ScriptableRenderPass API, that gets called by the renderer before rendering each camera -- Added a OnCameraCleanup() function to the ScriptableRenderPass API, that gets called by the renderer after rendering each camera -- Added Default Material Type options to the 2D Renderer Data Asset property settings. -- Added additional steps to the 2D Renderer setup page for quality and platform settings. -- Added option to disable XR autotests on test settings. -- Shader Preprocessor strips gbuffer shader variants if DeferredRenderer is not in the list of renderers in any Scriptable Pipeline Assets. -- Added an option to enable/disable Adaptive Performance when the Adaptive Performance package is available in the project. -- Added support for 3DsMax's 2021 Simplified Physical Material from FBX files in the Model Importer. -- Added GI to SpeedTree -- Added support for DXT5nm-style normal maps on Android, iOS and tvOS -- Added stencil override support for deferred renderer. -- Added a warning message when a renderer is used with an unsupported graphics API, as the deferred renderer does not officially support GL-based platforms. -- Added option to skip a number of final bloom iterations. -- Added support for [Screen Space Ambient Occlusion](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.0/manual/post-processing-ssao.html) and a new shader variant _SCREEN_SPACE_OCCLUSION. -- Added support for Normal Texture being generated in a prepass. -- Added a ConfigureInput() function to ScriptableRenderPass, so it is possible for passes to ask that a Depth, Normal and/or Opaque textures to be generated by the forward renderer. -- Added a float2 normalizedScreenSpaceUV to the InputData Struct. -- Added new sections to documentation: [Writing custom shaders](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.0/manual/writing-custom-shaders-urp.html), and [Using the beginCameraRendering event](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.0/manual/using-begincamerarendering.html). -- Added support for GPU instanced mesh particles on supported platforms. -- Added API to check if a Camera or Light is compatible with Universal Render Pipeline. - -### Changed -- Moved the icon that indicates the type of a Light 2D from the Inspector header to the Light Type field. -- Eliminated some GC allocations from the 2D Renderer. -- Added SceneSelection pass for TerrainLit shader. -- Remove final blit pass to force alpha to 1.0 on mobile platforms. -- Deprecated the CinemachineUniversalPixelPerfect extension. Use the one from Cinemachine v2.4 instead. -- Replaced PlayerSettings.virtualRealitySupported with XRGraphics.tryEnable. -- Blend Style in the 2DRendererData are now automatically enabled/disabled. -- When using the 2D Renderer, Sprites will render with a faster rendering path when no lights are present. -- Particle shaders now receive shadows -- The Scene view now mirrors the Volume Layer Mask set on the Main Camera. -- Drawing order of SRPDefaultUnlit is now the same as the Built-in Render Pipline. -- Made MaterialDescriptionPreprocessors private. -- UniversalRenderPipelineAsset no longer supports presets. [Case 1197020](https://issuetracker.unity3d.com/issues/urp-reset-functionality-does-not-work-on-preset-of-universalrenderpipelineassets). -- The number of maximum visible lights is now determined by whether the platform is mobile or not. -- Renderer Feature list is now redesigned to fit more closely to the Volume Profile UI, this vastly improves UX and reliability of the Renderer Features List. -- Default color values for Lit and SimpleLit shaders changed to white due to issues with texture based workflows. -- You can now subclass ForwardRenderer to create a custom renderer based on it. -- URP is now computing tangent space per fragment. -- Optimized the 2D Renderer to skip rendering into certain internal buffers when not necessary. -- You can now subclass ForwardRenderer to create a custom renderer based on it. -- URP shaders that contain a priority slider now no longer have an offset of 50 by default. -- The virtual ScriptableRenderer.FrameCleanup() function has been marked obsolete and replaced by ScriptableRenderer.OnCameraCleanup() to better describe when the function gets invoked by the renderer. -- DepthOnlyPass, CopyDepthPass and CopyColorPass now use OnCameraSetup() instead of Configure() to set up their passes before executing as they only need to get their rendertextures once per camera instead of once per eye. -- Updated shaders to be compatible with Microsoft's DXC. -- Mesh GPU Instancing option is now hidden from the particles system renderer as this feature is not supported by URP. -- The 2D Renderer now supports camera stacking. -- 2D shaders now use half-precision floats whenever precise results are not necessary. -- Removed the ETC1_EXTERNAL_ALPHA variant from Shader Graph Sprite shaders. -- Eliminated some unnecessary clearing of render targets when using the 2D Renderer. -- The rendering of 2D lights is more effient as sorting layers affected by the same set of lights are now batched. -- Removed the 8 renderer limit from URP Asset. -- Merged the deferred renderer into the forward renderer. -- Changing the default value of Skip Iterations to 1 in Bloom effect editor -- Use SystemInfo to check if multiview is supported instead of being platform hardcoded -- Default attachment setup behaviour for ScriptableRenderPasses that execute before rendering opaques is now set use current the active render target setup. This improves performance in some situations. -- Combine XR occlusion meshes into one when using single-pass (multiview or instancing) to reduce draw calls and state changes. -- Shaders included in the URP package now use local Material keywords instead of global keywords. This increases the amount of available global user-defined Material keywords. - -### Fixed -- Fixed an issue that caused WebGL to render blank screen when Depth texture was enabled [case 1240228](https://issuetracker.unity3d.com/issues/webgl-urp-scene-is-rendered-black-in-webgl-build-when-depth-texture-is-enabled) -- Fixed NaNs in tonemap algorithms (neutral and ACES) on Nintendo Switch. -- Fixed a performance problem with ShaderPreprocessor with large amount of active shader variants in the project -- Fixed an issue where linear to sRGB conversion occurred twice on certain Android devices. -- Fixed an issue where there were 2 widgets showing the outer angle of a spot light. -- Fixed an issue where Unity rendered fullscreen quads with the pink error shader when you enabled the Stop NaN post-processing pass. -- Fixed an issue where Terrain hole Shader changes were missing. [Case 1179808](https://issuetracker.unity3d.com/issues/terrain-brush-tool-is-not-drawing-when-paint-holes-is-selected). -- Fixed an issue where the Shader Graph `SceneDepth` node didn't work with XR single-pass (double-wide) rendering. See [case 1123069](https://issuetracker.unity3d.com/issues/lwrp-vr-shadergraph-scenedepth-doesnt-work-in-single-pass-rendering). -- Fixed Unlit and BakedLit shader compilations in the meta pass. -- Fixed an issue where the Bokeh Depth of Field shader would fail to compile on PS4. -- Fixed an issue where the Scene lighting button didn't work when you used the 2D Renderer. -- Fixed a performance regression when you used the 2D Renderer. -- Fixed an issue where the Freeform 2D Light gizmo didn't correctly show the Falloff offset. -- Fixed an issue where the 2D Renderer rendered nothing when you used shadow-casting lights with incompatible Renderer2DData. -- Fixed an issue where errors were generated when the Physics2D module was not included in the project's manifest. -- Fixed an issue where Prefab previews were incorrectly lit when you used the 2D Renderer. -- Fixed an issue where the Light didn't update correctly when you deleted a Sprite that a Sprite 2D Light uses. -- Fixed an issue where 2D Lighting was broken for Perspective Cameras. -- Fixed an issue where resetting a Freeform 2D Light would throw null reference exceptions. [Case 1184536](https://issuetracker.unity3d.com/issues/lwrp-changing-light-type-to-freeform-after-clicking-on-reset-throws-multiple-arguementoutofrangeexception). -- Fixed an issue where Freeform 2D Lights were not culled correctly when there was a Falloff Offset. -- Fixed an issue where Tilemap palettes were invisible in the Tile Palette window when the 2D Renderer was in use. [Case 1162550](https://issuetracker.unity3d.com/issues/adding-tiles-in-the-tile-palette-makes-the-tiles-invisible). -- Fixed issue where black emission would cause unneccesary inspector UI repaints. [Case 1105661](https://issuetracker.unity3d.com/issues/lwrp-inspector-window-is-being-repainted-when-using-the-material-with-emission-enabled-and-set-to-black-00-0). -- Fixed user LUT sampling being done in Linear instead of sRGB. -- Fixed an issue when trying to get the Renderer via API on the first frame. [Case 1189196](https://issuetracker.unity3d.com/product/unity/issues/guid/1189196/). -- Fixed a material leak on domain reload. -- Fixed an issue where deleting an entry from the Renderer List and then undoing that change could cause a null reference. [Case 1191896](https://issuetracker.unity3d.com/issues/nullreferenceexception-when-attempting-to-remove-entry-from-renderer-features-list-after-it-has-been-removed-and-then-undone). -- Fixed an issue where the user would get an error if they removed the Additional Camera Data component. [Case 1189926](https://issuetracker.unity3d.com/issues/unable-to-remove-universal-slash-hd-additional-camera-data-component-serializedobject-target-destroyed-error-is-thrown). -- Fixed post-processing with XR single-pass rendering modes. -- Fixed an issue where Cinemachine v2.4 couldn't be used together with Universal RP due to a circular dependency between the two packages. -- Fixed an issue that caused shaders containing `HDRP` string in their path to be stripped from the build. -- Fixed an issue that caused only selected object to render in SceneView when Wireframe drawmode was selected. -- Fixed Renderer Features UI tooltips. [Case 1191901](https://issuetracker.unity3d.com/issues/forward-renderers-render-objects-layer-mask-tooltip-is-incorrect-and-contains-a-typo). -- Fixed multiple issues where Shader Graph shaders failed to build for XR in the Universal RP. -- Fixed an issue when using the 2D Renderer where some types of renderers would not be assigned the correct material. -- Fixed inconsistent lighting between the forward renderer and the deferred renderer, that was caused by a missing normalize operation on vertex normals on some speedtree shader variants. -- Fixed issue where XR Multiview failed to render when using URP Shader Graph Shaders -- Fixed lazy initialization with last version of ResourceReloader -- Fixed broken images in package documentation. -- Fixed an issue where viewport aspect ratio was wrong when using the Stretch Fill option of the Pixel Perfect Camera. [case 1188695](https://issuetracker.unity3d.com/issues/pixel-perfect-camera-component-does-not-maintain-the-aspect-ratio-when-the-stretch-fill-is-enabled) -- Fixed an issue where setting a Normal map on a newly created material would not update. [case 1197217](https://issuetracker.unity3d.com/product/unity/issues/guid/1197217/) -- Fixed an issue where post-processing was not applied for custom renderers set to run on the "After Rendering" event [case 1196219](https://issuetracker.unity3d.com/issues/urp-post-processing-is-not-applied-to-the-scene-when-render-ui-event-is-set-to-after-rendering) -- Fixed an issue that caused an extra blit when using custom renderers [case 1156741](https://issuetracker.unity3d.com/issues/lwrp-performance-decrease-when-using-a-scriptablerendererfeature) -- Fixed an issue with transparent objects not receiving shadows when using shadow cascades. [case 1116936](https://issuetracker.unity3d.com/issues/lwrp-cascaded-shadows-do-not-appear-on-alpha-blended-objects) -- Fixed issue where using a ForwardRendererData preset would cause a crash. [case 1201052](https://issuetracker.unity3d.com/product/unity/issues/guid/1201052/) -- Fixed an issue where particles had dark outlines when blended together [case 1199812](https://issuetracker.unity3d.com/issues/urp-soft-particles-create-dark-blending-artefacts-when-intersecting-with-scene-geometry) -- Fixed an issue with deleting shader passes in the custom renderer features list [case 1201664](https://issuetracker.unity3d.com/issues/urp-remove-button-is-not-activated-in-shader-passes-list-after-creating-objects-from-renderer-features-in-urpassets-renderer) -- Fixed camera inverse view-projection matrix in XR mode, depth-copy and color-copy passes. -- Fixed an issue with the null check when `UniversalRenderPipelineLightEditor.cs` tries to access `SceneView.lastActiveSceneView`. -- Fixed an issue where the 'Depth Texture' drop down was incorrectly disabled in the Camera Inspector. -- Fixed an issue that caused errors if you disabled the VR Module when building a project. -- Fixed an issue where the default TerrainLit Material was outdated, which caused the default Terrain to use per-vertex normals instead of per-pixel normals. -- Fixed shader errors and warnings in the default Universal RP Terrain Shader. [case 1185948](https://issuetracker.unity3d.com/issues/urp-terrain-slash-lit-base-pass-shader-does-not-compile) -- Fixed an issue where the URP Material Upgrader tried to upgrade standard Universal Shaders. [case 1144710](https://issuetracker.unity3d.com/issues/upgrading-to-lwrp-materials-is-trying-to-upgrade-lwrp-materials) -- Fixed an issue where some Materials threw errors when you upgraded them to Universal Shaders. [case 1200938](https://issuetracker.unity3d.com/issues/universal-some-materials-throw-errors-when-updated-to-universal-rp-through-update-materials-to-universal-rp) -- Fixed issue where normal maps on terrain appeared to have flipped X-components when compared to the same normal map on a mesh. [case 1181518](https://fogbugz.unity3d.com/f/cases/1181518/) -- Fixed an issue where the editor would sometimes crash when using additional lights [case 1176131](https://issuetracker.unity3d.com/issues/mac-crash-on-processshadowcasternodevisibilityandcullwithoutumbra-when-same-rp-asset-is-set-in-graphics-and-quality-settings) -- Fixed RemoveComponent on Camera contextual menu to not remove Camera while a component depend on it. -- Fixed an issue where right eye is not rendered to. [case 1170619](https://issuetracker.unity3d.com/issues/vr-lwrp-terrain-is-not-rendered-in-the-right-eye-of-an-hmd-when-using-single-pass-instanced-stereo-rendering-mode-with-lwrp) -- Fixed issue where TerrainDetailLit.shader fails to compile when XR is enabled. -- Fixed an issue that allowed height-based blending on Terrains with more than 4 materials, which is not supported. -- Fixed an issue where opaque objects were outputting incorrect alpha values [case 1168283](https://issuetracker.unity3d.com/issues/lwrp-alpha-clipping-material-makes-other-materials-look-like-alpha-clipping-when-gameobject-is-shown-in-render-texture) -- Fixed an issue where a depth texture was always created when post-processing was enabled, even if no effects made use of it. -- Fixed incorrect light attenuation on Nintendo Switch. -- Fixed an issue where the Volume System would not use the Cameras Transform when no `Volume Trigger` was set. -- Fixed an issue where post processing disappeared when using custom renderers and SMAA or no AA -- Fixed an issue where the 2D Renderer upgrader did not upgrade using the correct default material -- Fixed an issue with soft particles having dark blending when intersecting with scene geometry [case 1199812](https://issuetracker.unity3d.com/issues/urp-soft-particles-create-dark-blending-artefacts-when-intersecting-with-scene-geometry) -- Fixed an issue with additive particles blending incorrectly [case 1215713](https://issuetracker.unity3d.com/issues/universal-render-pipeline-additive-particles-not-using-vertex-alpha) -- Fixed an issue where camera preview window was missing in scene view. [case 1211971](https://issuetracker.unity3d.com/issues/scene-view-urp-camera-preview-window-is-missing-in-the-scene-view) -- Fixed an issue with shadow cascade values were not readable in the render pipeline asset [case 1219003](https://issuetracker.unity3d.com/issues/urp-cascade-values-truncated-on-selecting-two-or-four-cascades-in-shadows-under-universalrenderpipelineasset) -- Fixed an issue where MSAA isn't applied until eye textures are relocated by changing their resolution. [case 1197958](https://issuetracker.unity3d.com/issues/oculus-quest-oculus-go-urp-msaa-isnt-applied-until-eye-textures-are-relocated-by-changing-their-resolution) -- Fixed an issue where camera stacking didn't work properly inside prefab mode. [case 1220509](https://issuetracker.unity3d.com/issues/urp-cannot-assign-overlay-cameras-to-a-camera-stack-while-in-prefab-mode) -- Fixed the definition of `mad()` in SMAA shader for OpenGL. -- Fixed an issue where partical shaders failed to handle Single-Pass Stereo VR rendering with Double-Wide Textures. [case 1201208](https://issuetracker.unity3d.com/issues/urp-vr-each-eye-uses-the-cameraopaquetexture-of-both-eyes-for-rendering-when-using-single-pass-rendering-mode) -- Fixed an issue that caused assets to be reimported if player prefs were cleared. [case 1192259](https://issuetracker.unity3d.com/issues/lwrp-clearing-playerprefs-through-a-script-or-editor-causes-delay-and-console-errors-to-appear-when-entering-the-play-mode) -- Fixed missing Custom Render Features after Library deletion. [case 1196338](https://issuetracker.unity3d.com/product/unity/issues/guid/1196338/) -- Fixed not being able to remove a Renderer Feature due to tricky UI selection rects. [case 1208113](https://issuetracker.unity3d.com/product/unity/issues/guid/1208113/) -- Fixed an issue where the Camera Override on the Render Object Feature would not work with many Render Features in a row. [case 1205185](https://issuetracker.unity3d.com/product/unity/issues/guid/1205185/) -- Fixed UI clipping issue in Forward Renderer inspector. [case 1211954](https://issuetracker.unity3d.com/product/unity/issues/guid/1211954/) -- Fixed a Null ref when trying to remove a missing Renderer Feature from the Forward Renderer. [case 1196651](https://issuetracker.unity3d.com/product/unity/issues/guid/1196651/) -- Fixed data serialization issue when adding a Renderer Feature to teh Forward Renderer. [case 1214779](https://issuetracker.unity3d.com/product/unity/issues/guid/1214779/) -- Fixed issue with AssetPostprocessors dependencies causing models to be imported twice when upgrading the package version. -- Fixed an issue where NullReferenceException might be thrown when creating 2D Lights. [case 1219374](https://issuetracker.unity3d.com/issues/urp-nullreferenceexception-threw-on-adding-the-light-2d-experimental-component-when-2d-render-data-not-assigned) -- Fixed an issue with a blurry settings icon. [case 1201895](https://issuetracker.unity3d.com/issues/urp-setting-icon-blurred-in-universalrendererpipelineasset) -- Fixed issue that caused the QualitySettings anti-aliasing changing without user interaction. [case 1195272](https://issuetracker.unity3d.com/issues/lwrp-the-anti-alias-quality-settings-value-is-changing-without-user-interaction) -- Fixed an issue where Shader Graph shaders generate undeclared identifier 'GetWorldSpaceNormalizeViewDir' error. -- Fixed an issue where rendering into RenderTexture with Single Pass Instanced renders both eyes overlapping. -- Fixed an issue where Renderscale setting has no effect when using XRSDK. -- Fixed an issue where renderScale != 1 or Display.main.requiresBlitToBackbuffer forced an unnecessary blit on XR. -- Fixed an issue that causes double sRGB correction on Quest. [case 1209292](https://issuetracker.unity3d.com/product/unity/issues/guid/1209292) -- Fixed an issue where terrain DepthOnly pass does not work for XR. -- Fixed an issue that caused depth texture to be flipped when sampling from shaders [case 1225362](https://issuetracker.unity3d.com/issues/game-object-is-rendered-incorrectly-in-the-game-view-when-sampling-depth-texture) -- Fixed an issue with URP switching such that every avaiable URP makes a total set of supported features such that all URPs are taken into consideration. [case 1157420](https://issuetracker.unity3d.com/issues/lwrp-srp-switching-doesnt-work-even-with-manually-adding-shadervariants-per-scene) -- Fixed an issue where XR multipass repeatedly throws error messages "Multi pass stereo mode doesn't support Camera Stacking". -- Fixed an issue with shadows not appearing on terrains when no cascades were selected [case 1226530](https://issuetracker.unity3d.com/issues/urp-no-shadows-on-terrain-when-cascades-is-set-to-no-cascades-in-render-pipeline-asset-settings) -- Fixed a shader issue that caused the Color in Sprite Shape to work improperly. -- Fixed an issue with URP switching such that every available URP makes a total set of supported features such that all URPs are taken into consideration. [case 1157420](https://issuetracker.unity3d.com/issues/lwrp-srp-switching-doesnt-work-even-with-manually-adding-shadervariants-per-scene) -- Metallic slider on the Lit shader is now linear meaning correct values are used for PBR. -- Fixed an issue where Post-Processing caused nothing to render on GLES2. -- Fixed an issue that causes viewport to not work correctly when rendering to textures. [case 1225103](https://issuetracker.unity3d.com/issues/urp-the-viewport-rect-isnt-correctly-applied-when-the-camera-is-outputting-into-a-rendertexture) -- Fixed an issue that caused incorrect sampling of HDR reflection probe textures. -- Fixed UI text of RenderObjects feature to display LightMode tag instead of Shader Pass Name. [case 1201696](https://issuetracker.unity3d.com/issues/render-feature-slash-pass-ui-has-a-field-for-shader-pass-name-when-it-actually-expects-shader-pass-lightmode) -- Fixed an issue when Linear -> sRGB conversion would not happen on some Android devices. [case 1226208](https://issuetracker.unity3d.com/issues/no-srgb-conversion-on-some-android-devices-when-using-the-universal-render-pipeline) -- Fixed issue where using DOF at the same time as Dynamic Scaling, the depth buffer was smapled with incorrect UVs. [case 1225467](https://issuetracker.unity3d.com/product/unity/issues/guid/1225467/) -- Fixed an issue where an exception would be thrown when resetting the ShadowCaster2D component. [case 1225339](https://issuetracker.unity3d.com/issues/urp-unassignedreferenceexception-thrown-on-resetting-the-shadow-caster-2d-component) -- Fixe an issue where using a Subtractive Blend Style for your 2D Lights might cause artifacts in certain post-processing effects. [case 1215584](https://issuetracker.unity3d.com/issues/urp-incorrect-colors-in-scene-when-using-subtractive-and-multiply-blend-mode-in-gamma-color-space) -- Fixed an issue where Cinemachine Pixel Perfect Extension didn't work when CinemachineBrain Update Method is anything other than Late Update. -- Fixed an issue where Sprite Shader Graph shaders weren't double-sided by default. -- Fixed an issue where particles using Sprite Shader Graph shaders were invisible. -- Fixed an issue where Scene objects might be incorrectly affected by 2D Lights from a previous Sorting Layer. -- Fixed an issue where errors would appear in the Console when entering Play Mode with a 2D Light selected in the Hierarchy. [Case 1226918](https://issuetracker.unity3d.com/issues/errors-appear-in-the-console-when-global-2d-light-is-selected-in-hierarchy) -- Fixed an issue that caused Android GLES to render blank screen when Depth texture was enabled without Opaque texture [case 1219325](https://issuetracker.unity3d.com/issues/scene-is-not-rendered-on-android-8-and-9-when-depth-texture-is-enabled-in-urp-asset) -- Fixed an issue that caused transparent objects to always render over top of world space UI. [case 1219877](https://issuetracker.unity3d.com/product/unity/issues/guid/1219877/) -- Fixed issue causing sorting fudge to not work between shadergraph and urp particle shaders. [case 1222762](https://issuetracker.unity3d.com/product/unity/issues/guid/1222762/) -- Fixed shader compilation errors when using multiple lights in DX10 level GPU. [case 1222302](https://issuetracker.unity3d.com/issues/urp-no-materials-apart-from-ui-are-rendered-when-using-direct3d11-graphics-api-on-a-dx10-gpu) -- Fixed an issue with shadows not being correctly calculated in some shaders. -- Fixed invalid implementation of one function in LWRP -> URP backward compatibility support. -- Fixed issue on Nintendo Switch where maximum number of visible lights in C# code did not match maximum number in shader code. -- Fixed OpenGL ES 3.0 support for URP ShaderGraph. [case 1230890](https://issuetracker.unity3d.com/issues/urptemplate-gles3-android-custom-shader-fails-to-compile-on-adreno-306-gpu) -- Fixed an issue where multi edit camera properties didn't work. [case 1230080](https://issuetracker.unity3d.com/issues/urp-certain-settings-are-not-applied-to-all-cameras-when-multi-editing-in-the-inspector) -- Fixed an issue where the emission value in particle shaders would not update in the editor without entering the Play mode. -- Fixed issues with performance when importing fbx files. -- Fixed issues with NullReferenceException happening with URP shaders. -- Fixed an issue that caused memory allocations when sorting cameras. [case 1226448](https://issuetracker.unity3d.com/issues/2d-renderer-using-more-than-one-camera-that-renders-out-to-a-render-texture-creates-gc-alloc-every-frame) -- Fixed an issue where grid lines were drawn on top of opaque objects in the preview window. [Case 1240723](https://issuetracker.unity3d.com/issues/urp-grid-is-rendered-in-front-of-the-model-in-the-inspector-animation-preview-window-when-depth-or-opaque-texture-is-enabled). -- Fixed an issue where objects in the preview window were affected by layer mask settings in the default renderer. [Case 1204376](https://issuetracker.unity3d.com/issues/urp-prefab-preview-is-blank-when-a-custom-forward-renderer-data-and-default-layer-mask-is-mixed-are-used). -- Fixed an issue with reflections when using an orthographic camera [case 1209255](https://issuetracker.unity3d.com/issues/urp-weird-reflections-when-using-lit-material-and-a-camera-with-orthographic-projection) -- Fixed issue that caused unity_AmbientSky, unity_AmbientEquator and unity_AmbientGround variables to be unintialized. -- Fixed issue that caused `SHADERGRAPH_AMBIENT_SKY`, `SHADERGRAPH_AMBIENT_EQUATOR` and `SHADERGRAPH_AMBIENT_GROUND` variables to be uninitialized. -- Fixed SceneView Draw Modes not being properly updated after opening new scene view panels or changing the editor layout. -- Fixed GLES shaders compilation failing on Windows platform (not a mobile platform) due to uniform count limit. -- Fixed an issue that caused the inverse view and projection matrix to output wrong values in some platforms. [case 1243990](https://issuetracker.unity3d.com/issues/urp-8-dot-1-breaks-unity-matrix-i-vp) -- Fixed an issue where the Render Scale setting of the pipeline asset didn't properly change the resolution when using the 2D Renderer. [case 1241537](https://issuetracker.unity3d.com/issues/render-scale-is-not-applied-to-the-rendered-image-when-2d-renderer-is-used-and-hdr-option-is-disabled) -- Fixed an issue where 2D lights didn't respect the Camera's Culling Mask. [case 1239136](https://issuetracker.unity3d.com/issues/urp-2d-2d-lights-are-ignored-by-camera-culling-mask) -- Fixed broken documentation links for some 2D related components. -- Fixed an issue where Sprite shaders generated by Shader Graph weren't double-sided. [case 1261232](https://issuetracker.unity3d.com/product/unity/issues/guid/1261232/) -- Fixed an issue where the package would fail to compile if the Animation module was disabled. [case 1227068](https://issuetracker.unity3d.com/product/unity/issues/guid/1227068/) -- Fixed an issue where Stencil settings wasn't serialized properly in sub object [case 1241218](https://issuetracker.unity3d.com/issues/stencil-overrides-in-urp-7-dot-3-1-render-objects-does-not-save-or-apply) -- Fixed an issue with not being able to remove Light Mode Tags [case 1240895](https://issuetracker.unity3d.com/issues/urp-unable-to-remove-added-lightmode-tags-of-filters-property-in-render-object) -- Fixed an issue where preset button could still be used, when it is not supposed to. [case 1246261](https://issuetracker.unity3d.com/issues/urp-reset-functionality-does-not-work-for-renderobject-preset-asset) -- Fixed an issue where Model Importer Materials used the Standard Shader from the Built-in Render Pipeline instead of URP Lit shader when the import happened at Editor startup. -- Fixed an issue where only unique names of cameras could be added to the camera stack. -- Fixed issue that caused shaders to fail to compile in OpenGL 4.1 or below. -- Fixed an issue where camera stacking with MSAA on OpenGL resulted in a black screen. [case 1250602](https://issuetracker.unity3d.com/issues/urp-camera-stacking-results-in-black-screen-when-msaa-and-opengl-graphics-api-are-used) -- Optimized shader compilation times by compiling different variant sets for vertex and fragment shaders. -- Fixed shadows for additional lights by limiting MAX_VISIBLE_LIGHTS to 16 for OpenGL ES 2.0 and 3.0 on mobile platforms. [case 1244391](https://issuetracker.unity3d.com/issues/android-urp-spotlight-shadows-are-not-being-rendered-on-adreno-330-and-320-when-built) -- Fixed Lit/SimpleLit/ParticlesLit/ParticlesSimpleLit/ParticlesUnlit shaders emission color not to be converted from gamma to linear color space. [case 1249615] -- Fixed missing unity_MatrixInvP for shader code and shaderGraph. -- Fixed XR support for deferred renderer. -- Fixing RenderObject to reflect name changes done at CustomForwardRenderer asset in project view. [case 1246256](https://issuetracker.unity3d.com/issues/urp-renderobject-name-does-not-reflect-inside-customforwardrendererdata-asset-on-renaming-in-the-inspector) -- Fixing camera overlay stacking adding to respect unity general reference restrictions. [case 1240788](https://issuetracker.unity3d.com/issues/urp-overlay-camera-is-missing-in-stack-list-of-the-base-camera-prefab) -- Fixed profiler marker errors. [case 1240963](https://issuetracker.unity3d.com/issues/urp-errors-are-thrown-in-a-console-when-using-profiler-to-profile-editor) -- Fixed issue that caused the pipeline to not create _CameraColorTexture if a custom render pass is injected. [case 1232761](https://issuetracker.unity3d.com/issues/urp-the-intermediate-color-texture-is-no-longer-created-when-there-is-at-least-one-renderer-feature) -- Fixed target eye UI for XR rendering is missing from camera inspector. [case 1261612](https://issuetracker.unity3d.com/issues/xr-cameras-target-eye-property-is-missing-when-inspector-is-in-normal-mode) -- Fixed an issue where terrain and speedtree materials would not get upgraded by upgrade project materials. [case 1204189](https://fogbugz.unity3d.com/f/cases/1204189/) -- Fixed an issue that caused renderer feature to not render correctly if the pass was injected before rendering opaques and didn't implement `Configure` method. [case 1259750](https://issuetracker.unity3d.com/issues/urp-not-rendering-with-a-renderer-feature-before-rendering-shadows) -- Fixed an issue where postFX's temp texture is not released properly. -- Fixed an issue where ArgumentOutOfRangeException errors were thrown after removing Render feature [case 1268147](https://issuetracker.unity3d.com/issues/urp-argumentoutofrangeexception-errors-are-thrown-on-undoing-after-removing-render-feature) -- Fixed an issue where depth and depth/normal of grass isn't rendered to depth texture. -- Fixed an issue that impacted MSAA performance on iOS/Metal [case 1219054](https://issuetracker.unity3d.com/issues/urp-ios-msaa-has-a-bigger-negative-impact-on-performance-when-using-urp-compared-to-built-in-rp) -- Fixed an issue that caused a warning to be thrown about temporary render texture not found when user calls ConfigureTarget(0). [case 1220871](https://issuetracker.unity3d.com/issues/urp-scriptable-render-passes-which-dont-require-a-bound-render-target-triggers-render-target-warning) -- Fixed performance issues in the C# shader stripper. - -## [7.1.1] - 2019-09-05 -### Upgrade Guide -- The render pipeline now handles custom renderers differently. You must now set up renderers for the Camera on the Render Pipeline Asset. -- Render Pipeline Assets upgrades automatically and either creates a default forward renderer in your project or links the existing custom one that you've assigned. -- If you have custom renderers assigned to Cameras, you must now add them to the current Render Pipeline Asset. Then you can select which renderer to use on the Camera. - -### Added -- Added shader function `GetMainLightShadowParams`. This returns a half4 for the main light that packs shadow strength in x component and shadow soft property in y component. -- Added shader function `GetAdditionalLightShadowParams`. This returns a half4 for an additional light that packs shadow strength in x component and shadow soft property in y component. -- Added a `Debug Level` option to the Render Pipeline Asset. With this, you can control the amount of debug information generated by the render pipeline. -- Added ability to set the `ScriptableRenderer` that the Camera renders with via C# using `UniversalAdditionalCameraData.SetRenderer(int index)`. This maps to the **Renderer List** on the Render Pipeline Asset. -- Added shadow support for the 2D Renderer. -- Added ShadowCaster2D, and CompositeShadowCaster2D components. -- Added shadow intensity and shadow volume intensity properties to Light2D. -- Added new Gizmos for Lights. -- Added CinemachineUniversalPixelPerfect, a Cinemachine Virtual Camera Extension that solves some compatibility issues between Cinemachine and Pixel Perfect Camera. -- Added an option that disables the depth/stencil buffer for the 2D Renderer. -- Added manipulation handles for the inner cone angle for spot lights. -- Added documentation for the built-in post-processing solution and Volumes framework (and removed incorrect mention of the PPv2 package). - -### Changed -- Increased visible lights limit for the forward renderer. It now supports 256 visible lights except in mobile platforms. Mobile platforms support 32 visible lights. -- Increased per-object lights limit for the forward renderer. It now supports 8 per-object lights in all platforms except GLES2. GLES2 supports 4 per-object lights. -- The Sprite-Lit-Default shader and the Sprite Lit Shader Graph shaders now use the vertex tangents for tangent space calculations. -- Temporary render textures for cameras rendering to render textures now use the same format and multisampling configuration as camera's target texture. -- All platforms now use R11G11B10_UFloat format for HDR render textures if supported. -- There is now a list of `ScriptableRendererData` on the Render Pipeline Asset as opposed to a renderer type. These are available to all Cameras and are included in builds. -- The renderer override on the Camera is now an enum that maps to the list of `ScriptableRendererData` on the Render Pipeline Asset. -- Pixel Perfect Camera now allows rendering to a render texture. -- Light2D GameObjects that you've created now have a default position with z equal to 0. -- Documentation: Changed the "Getting Started" section into "Install and Configure". Re-arranged the Table of Content. - -### Fixed -- Fixed LightProbe occlusion contribution. [case 1146667](https://issuetracker.unity3d.com/product/unity/issues/guid/1146667/) -- Fixed an issue that caused a log message to be printed in the console when creating a new Material. [case 1173160](https://issuetracker.unity3d.com/product/unity/issues/guid/1173160/) -- Fixed an issue where OnRenderObjectCallback was never invoked. [case 1122420](https://issuetracker.unity3d.com/issues/lwrp-gl-dot-lines-and-debug-dot-drawline-dont-render-when-scriptable-render-pipeline-settings-is-set-to-lwrp) -- Fixed an issue where Sprite Masks didn't function properly when using the 2D Renderer. [case 1163474](https://issuetracker.unity3d.com/issues/lwrp-sprite-renderer-ignores-sprite-mask-when-lightweight-render-pipeline-asset-data-is-set-to-2d-renderer-experimental) -- Fixed memory leaks when using the Frame Debugger with the 2D Renderer. -- Fixed an issue where materials using `_Time` did not animate in the scene. [1175396](https://issuetracker.unity3d.com/product/unity/issues/guid/1175396/) -- Fixed an issue where the Particle Lit shader had artifacts when both soft particles and HDR were enabled. [1136285](https://issuetracker.unity3d.com/product/unity/issues/guid/1136285/) -- Fixed an issue where the Area Lights were set to Realtime, which caused them to not bake. [1159838](https://issuetracker.unity3d.com/issues/lwrp-template-baked-area-lights-do-not-work-if-project-is-created-with-lightweight-rp-template) -- Fixed an issue where the Disc Light did not generate any light. [1175097](https://issuetracker.unity3d.com/issues/using-lwrp-area-light-does-not-generate-light-when-its-shape-is-set-to-disc) -- Fixed an issue where the alpha was killed when an opaque texture was requested on an offscreen camera with HDR enabled [case 1163320](https://issuetracker.unity3d.com/issues/lwrp-mobile-secondary-camera-background-alpha-value-is-lost-when-hdr-and-opaque-texture-are-enabled-in-lwrp-asset). -- Fixed an issue that caused Orthographic camera with far plane set to 0 to span Unity console with errors. [case 1172269](https://issuetracker.unity3d.com/issues/orthographic-camera-with-far-plane-set-to-0-results-in-assertions) -- Fixed an issue causing heap allocation in `RenderPipelineManager.DoRenderLoop` [case 1156241](https://issuetracker.unity3d.com/issues/lwrp-playerloop-renderpipelinemanager-dot-dorenderloop-internal-gc-dot-alloc-allocates-around-2-dot-6kb-for-every-camera-in-the-scene) -- Fixed an issue that caused shadow artifacts when using large spot angle values [case 1136165](https://issuetracker.unity3d.com/issues/lwrp-adjusting-spot-angle-on-a-spotlight-produces-shadowmap-artifacts) -- Fixed an issue that caused self-shadowing artifacts when adjusting shadow near-plane on spot lights. -- Fixed an issue that caused specular highlights to disappear when the smoothness value was set to 1.0. [case 1161827](https://issuetracker.unity3d.com/issues/lwrp-hdrp-lit-shader-max-smoothness-value-is-incosistent-between-pipelines) -- Fixed an issue in the Material upgrader that caused transparent Materials to not upgrade correctly to Universal RP. [case 1170419](https://issuetracker.unity3d.com/issues/shader-conversion-upgrading-project-materials-causes-standard-transparent-materials-to-flicker-when-moving-the-camera). -- Fixed an issue causing shadows to be incorrectly rendered when a light was close to the shadow caster. -- Fixed post-processing for the 2D Renderer. -- Fixed an issue in Light2D that caused a black line to appear for a 360 degree spotlight. -- Fixed a post-processing rendering issue with non-fullscreen viewport. [case 1177660](https://issuetracker.unity3d.com/issues/urp-render-scale-slider-value-modifies-viewport-coordinates-of-the-screen-instead-of-the-resolution) -- Fixed an issue where **Undo** would not undo the creation of Additional Camera Data. [case 1158861](https://issuetracker.unity3d.com/issues/lwrp-additional-camera-data-script-component-appears-on-camera-after-manually-re-picking-use-pipeline-settings) -- Fixed an issue where selecting the same drop-down menu item twice would trigger a change event. [case 1158861](https://issuetracker.unity3d.com/issues/lwrp-additional-camera-data-script-component-appears-on-camera-after-manually-re-picking-use-pipeline-settings) -- Fixed an issue where selecting certain objects that use instancing materials would throw console warnings. [case 1127324](https://issuetracker.unity3d.com/issues/console-warning-is-being-spammed-when-having-lwrp-enabled-and-shader-with-gpu-instancing-present-in-the-scene) -- Fixed a GUID conflict with LWRP. [case 1179895](https://issuetracker.unity3d.com/product/unity/issues/guid/1179895/) -- Fixed an issue where the Terrain shader generated NaNs. -- Fixed an issue that caused the `Opaque Color` pass to never render at half or quarter resolution. -- Fixed and issue where stencil state on a `ForwardRendererData` was reset each time rendering happened. - -## [7.0.1] - 2019-07-25 -### Changed -- Platform checks now provide more helpful feedback about supported features in the Inspectors. - -### Fixed -- Fixed specular lighting related artifacts on Mobile [case 1143049](https://issuetracker.unity3d.com/issues/ios-lwrp-rounded-cubes-has-graphical-artifacts-when-setting-pbr-shaders-smoothness-about-to-0-dot-65-in-shadergraph) and [case 1164822](https://issuetracker.unity3d.com/issues/lwrp-specular-highlight-becomes-hard-edged-when-increasing-the-size-of-an-object). -- Post-processing is no longer enabled in the previews. -- Unity no longer force-enables post-processing on a camera by default. -- Fixed an issue that caused the Scene to render darker in GLES3 and linear color space. [case 1169789](https://issuetracker.unity3d.com/issues/lwrp-android-scene-is-rendered-darker-in-build-when-graphics-api-set-to-gles3-and-color-space-set-to-linear) - -## [7.0.0] - 2019-07-17 -### Universal Render Pipeline -- LWRP has been renamed to the "Universal Render Pipeline" (UniversalRP). -- UniversalRP is the same as LWRP in terms of features and scope. -- Classes have moved to the Universal namespace (from LWRP). - -### Upgrade Guide -- Upgrading to UniversalRP is designed to be almost seamless from the user side. -- LWRP package still exists, this forwards includes and classes to the UniversalRP Package. -- Please see the more involved upgrade guide (https://docs.google.com/document/d/1Xd5bZa8pYZRHri-EnNkyhwrWEzSa15vtnpcg--xUCIs/). - -### Added -- Initial Stadia platform support. -- Added a menu option to create a new `ScriptableRendererFeature` script. To do so in the Editor, click on Asset > Create > Rendering > Lightweight Render Pipeline > Renderer Feature. -- Added documentation for SpeedTree Shaders in LWRP. -- Added extended features to LWRP Terrain Shader, so terrain assets can be forward-compatible with HDRP. -- Enabled per-layer advanced or legacy-mode blending in LWRP Terrain Shader. -- Added the documentation page "Rendering in LWRP", which describes the forward rendering camera loop. -- Added documentation overview for how Post Processing Version 2 works in LWRP. -- Added documentation notes and FAQ entry on the 2D Renderer affecting the LWRP Asset. - -### Changed -- Replaced beginCameraRendering callbacks by non obsolete implementation in Light2D -- Updated `ScriptableRendererFeature` and `ScriptableRenderPass` API docs. -- Shader type Real translates to FP16 precision on Nintendo Switch. - -### Fixed -- Fixed a case where built-in Shader time values could be out of sync with actual time. [case 1142495](https://fogbugz.unity3d.com/f/cases/1142495/) -- Fixed an issue that caused forward renderer resources to not load properly when you upgraded LWRP from an older version to 7.0.0. [case 1154925](https://issuetracker.unity3d.com/issues/lwrp-upgrading-lwrp-package-to-7-dot-0-0-breaks-forwardrenderdata-asset-in-resource-files) -- Fixed GC spikes caused by LWRP allocating heap memory every frame. -- Fixed distortion effect on particle unlit shader. -- Fixed NullReference exception caused when trying to add a ScriptableRendererFeature. -- Fixed issue with certain LWRP shaders not showing when using forward/2D renderer. -- Fixed the shadow resolve pass and the final pass, so they're not consuming unnecessary bandwidth. [case 1152439](https://issuetracker.unity3d.com/issues/lwrp-mobile-increased-memory-usage-and-extra-rendering-steps) -- Added missing page for 2D Lights in LWRP. -- Tilemap tiles no longer appear black when you use the 2D renderer. -- Sprites in the preview window are no longer lit by 2D Scene lighting. -- Fixed warnings for unsupported shadow map formats for GLES2 API. -- Disabled shadows for devices that do not support shadow maps or depth textures. -- Fixed support for LWRP per-pixel terrain. [case 1110520](https://fogbugz.unity3d.com/f/cases/1110520) -- Fixed some basic UI/usability issues with LWRP terrain Materials (use of warnings and modal value changes). -- Fixed an issue where using LWRP and Sprite Shape together would produce meta file conflicts. -- Fixed fp16 overflow in Switch in specular calculation -- Fixed shader compilation errors for Android XR projects. -- Updated the pipeline Asset UI to cap the render scale at 2x so that it matches the render pipeline implementation limit. - -## [6.7.0] - 2019-05-16 -### Added -- Added SpeedTree Shaders. -- Added two Shader Graph master nodes: Lit Sprite and Unlit Sprite. They only work with the 2D renderer. -- Added documentation for the 2D renderer. - -### Changed -- The 2D renderer and Light2D component received a number of improvements and are now ready to try as experimental features. -- Updated the [Feature Comparison Table](lwrp-builtin-feature-comparison.md) to reflect the current state of LWRP features. - -### Fixed -- When in playmode, the error 'Non matching Profiler.EndSample' no longer appears. [case 1140750](https://fogbugz.unity3d.com/f/cases/1140750/) -- LWRP Particle Shaders now correctly render in stereo rendering modes. [case 1106699](https://fogbugz.unity3d.com/f/cases/1106699/) -- Shaders with 'debug' in the name are no longer stripped automatically. [case 1112983](https://fogbugz.unity3d.com/f/cases/1112983/) -- Fixed tiling issue with selection outline and baked cutout shadows. -- in the Shadergraph Unlit Master node, Premultiply no longer acts the same as Alpha. [case 1114708](https://fogbugz.unity3d.com/f/cases/1114708/) -- Fixed an issue where Lightprobe data was missing if it was needed per-pixel and GPU instancing was enabled. -- The Soft ScreenSpaceShadows Shader variant no longer gets stripped form builds. [case 1138236](https://fogbugz.unity3d.com/f/cases/1138236/) -- Fixed a typo in the Particle Unlit Shader, so Soft Particles now work correctly. -- Fixed emissive Materials not being baked for some meshes. [case 1145297](https://issuetracker.unity3d.com/issues/lwrp-emissive-materials-are-not-baked) -- Camera matrices are now correctly set up when you call rendering functions in EndCameraRendering. [case 1146586](https://issuetracker.unity3d.com/issues/lwrp-drawmeshnow-returns-wrong-positions-slash-scales-when-called-from-endcamerarendering-hook) -- Fixed GI not baking correctly while in gamma color space. -- Fixed a NullReference exception when adding a renderer feature that is contained in a global namespace. [case 1147068](https://issuetracker.unity3d.com/issues/scriptablerenderpipeline-inspector-ui-crashes-when-a-scriptablerenderfeature-is-not-in-a-namespace) -- Shaders are now set up for VR stereo instancing on Vulkan. [case 1142952](https://fogbugz.unity3d.com/f/cases/1142952/). -- VR stereo matrices and vertex inputs are now set up on Vulkan. [case 1142952](https://fogbugz.unity3d.com/f/cases/1142952/). -- Fixed the Material Upgrader so it's now run upon updating the LWRP package. [1148764](https://issuetracker.unity3d.com/product/unity/issues/guid/1148764/) -- Fixed a NullReference exception when you create a new Lightweight Render Pipeline Asset. [case 1153388](https://issuetracker.unity3d.com/product/unity/issues/guid/1153388/) - -## [6.6.0] - 2019-04-01 -### Added -- Added support for Baked Indirect mixed lighting. -- You can now use Light Probes for occlusion. This means that baked lights can now occlude dynamic objects. -- Added RenderObjects. You can add RenderObjects to a Renderer to perform custom rendering. -- (WIP) Added an experimental 2D renderer that implements a 2D lighting system. -- (WIP) Added a Light2D component that works with the 2D renderer to add lighting effects to 2D sprites. - -### Fixed -- Fixed a project import issue in the LWRP template. -- Fixed the warnings that appear when you create new Unlit Shader Graphs using the Lightweight Render Pipeline. -- Fixed light attenuation precision on mobile platforms. -- Fixed split-screen rendering on mobile platforms. -- Fixed rendering when using an off-screen camera that renders to a depth texture. -- Fixed the exposed stencil render state in the renderer. -- Fixed the default layer mask so it's now applied to a depth pre-pass. -- Made several improvements and fixes to the render pass UI. -- Fixed artifacts that appeared due to precision errors in large scaled objects. -- Fixed an XR rendering issue where Unity required a depth texture. -- Fixed an issue that caused transparent objects to sort incorrectly. - -## [6.5.0] - 2019-03-07 -### Added -- You can now create a custom forward renderer by clicking on `Assets/Create/Rendering/Lightweight Render Pipeline/Forward Renderer`. This creates an Asset in your Project. You can add additional features to it and drag-n-drop the renderer to either the pipeline Asset or to a camera. -- You can now add `ScriptableRendererFeature` to the `ScriptableRenderer` to extend it with custom effects. A feature is an `ScriptableObject` that can be drag-n-dropped in the renderer and adds one or more `ScriptableRenderPass` to the renderer. -- `ScriptableRenderer` now exposes interface to configure lights. To do so, implement `SetupLights` when you create a new renderer. -- `ScriptableRenderer` now exposes interface to configure culling. To do so, implement `SetupCullingParameters` when you create a new renderer. -- `ScriptableRendererData` contains rendering resources for `ScriptableRenderer`. A renderer can be overridden globally for all cameras or on a per-camera basis. -- `ScriptableRenderPass` now has a `RenderPassEvents`. This controls where in the pipeline the render pass is added. -- `ScriptableRenderPass` now exposes `ConfigureTarget` and `ConfigureClear`. This allows the renderer to automatically figure out the currently active rendering targets. -- `ScriptableRenderPass` now exposes `Blit`. This performs a blit and sets the active render target in the renderer. -- `ScriptableRenderPass` now exposes `RenderPostProcessing`. This renders post-processing and sets the active render target in the renderer. -- `ScriptableRenderPass` now exposes `CreateDrawingSettings` as a helper for render passes that need to call `ScriptableRenderContext.DrawRenderers`. - -### Changed -- Removed `RegisterShaderPassName` from `ScriptableRenderPass`. Instead, `CreateDrawingSettings` now takes one or a list of `ShaderTagId`. -- Removed remaining experimental namespace from LWRP. All APIrelated to `ScriptableRenderer`, `ScriptableRenderPass`, and render pass injection is now out of preview. -- Removed `SetRenderTarget` from `ScriptableRenderPass`. You should never call it. Instead, call `ConfigureTarget`, and the renderer automatically sets up targets for you. -- Removed `RenderFullscreenQuad` from `ScriptableRenderer`. Use `CommandBuffer.DrawMesh` and `RenderingUtils.fullscreenMesh` instead. -- Removed `RenderPostProcess` from `ScriptableRenderer`. Use `ScriptableRenderPass.RenderPostProcessing` instead. -- Removed `postProcessingContext` property from `ScriptableRenderer`. This is now exposed in `RenderingUtils.postProcessingContext`. -- Removed `GetCameraClearFlag` from `ScriptableRenderer`. - -### Fixed -- Fixed y-flip in VR when post-processing is active. -- Fixed occlusion mesh for VR not rendering before rendering opaques. -- Enabling or disabling SRP Batcher in runtime works now. -- Fixed video player recorder when post-processing is enabled. - -## [6.4.0] - 2019-02-21 - -## [6.3.0] - 2019-02-18 - -## [6.2.0] - 2019-02-15 - -### Changed -- Code refactor: all macros with ARGS have been swapped with macros with PARAM. This is because the ARGS macros were incorrectly named. - -## [6.1.0] - 2019-02-13 - -## [6.0.0] - 2019-02-23 -### Added -- You can now implement a custom renderer for LWRP. To do so, implement an `IRendererData` that contains all resources used in rendering. Then create an `IRendererSetup` that creates and queues `ScriptableRenderPass`. Change the renderer type either in the Pipeline Asset or in the Camera Inspector. -- LWRP now uses the Unity recorder extension. You can use this to capture the output of Cameras. -- You can now inject a custom render pass before LWRP renders opaque objects. To do so, implement an `IBeforeRender` interface. -- Distortion support in all Particle Shaders. -- An upgrade system for LWRP Materials with `MaterialPostprocessor`. -- An upgrade path for Unlit shaders -- Tooltips for Shaders. -- SRP Batcher support for Particle Shaders. -- Docs for these Shaders: Baked Lit, Particles Lit, Particles Simple Lit, and Particles Unlit. -- LWRP now supports dynamic resolution scaling. The target platform must also support it. -- LWRP now includes version defines for both C# and Shaders in the format of `LWRP_X_Y_Z_OR_NEWER`. For example, `LWRP_5_3_0_OR_NEWER` defines version 5.3.0. -- The Terrain Lit Shader now samples Spherical Harmonics if you haven't baked any lightmaps for terrain. -- Added a __Priority__ option, which you can use to tweak the rendering order. This is similar to render queue in the built-in render pipeline. These Shaders now have this option: Lit, Simple Lit, Baked Lit, Unlit, and all three Particle Shaders. -- Added support for overriding terrain detail rendering shaders, via the render pipeline editor resources asset. - -### Changed -- You can now only initialize a camera by setting a Background Type. The supported options are Skybox, Solid Color, and Don't Care. -- LWRP now uses non-square shadowmap textures when it renders directional shadows with 2 shadow cascades. -- LWRP now uses RGB111110 as the HDR format on mobile devices, when this format is supported. -- Removed `IAfterDepthPrePass` interface. -- We’ve redesigned the Shader GUI. For example, all property names in Shaders are now inline across the board -- The Simple Lit Shader now has Smoothness, which can be stored in the alpha of specular or albedo maps. -- The Simple Lit and Particles Simple Lit Shaders now take shininess from the length (brightness) of the specular map. -- The __Double sided__ property is now __Render Face__. This means you can also do front face culling. -- Changed the docs for Lit Shader, Simple Lit Shader and Unlit Shader according to Shader GUI changes. -- When you create a new LWRP Asset, it will now be initialized with settings that favor performance on mobile platforms. -- Updated the [FAQ](faq.md) and the [Built-in/LWRP feature comparison table](lwrp-builtin-feature-comparison.md). - -### Fixed -- Several tweaks to reduce bandwidth consumption on mobile devices. -- The foldouts in the Lightweight Asset inspector UI now remember their state. -- Added missing meta file for GizmosRenderingPass.cs. -- Fixed artifacts when using multiple or Depth Only cameras. [Case 1072615](https://issuetracker.unity3d.com/issues/ios-using-multiple-cameras-in-the-scene-in-lightweight-render-pipeline-gives-corrupted-image-in-ios-device) -- Fixed a typo in ERROR_ON_UNSUPPORTED_FUNCTION() that was causing the shader compiler to run out of memory in GLES2. [Case 1104271](https://issuetracker.unity3d.com/issues/mobile-os-restarts-because-of-high-memory-usage-when-compiling-shaders-for-opengles2) -- LWRP now renders shadows on scaled objects correctly. [Case 1109017](https://issuetracker.unity3d.com/issues/scaled-objects-render-shadows-and-specularity-incorrectly-in-the-lwrp-on-device) -- LWRP now allows some Asset settings to be changed at runtime. [Case 1105552](https://issuetracker.unity3d.com/issues/lwrp-changing-render-scale-in-runtime-has-no-effect-since-lwrp-3-dot-3-0) -- Realtime shadows now work in GLES2. [Case 1087251](https://issuetracker.unity3d.com/issues/android-lwrp-no-real-time-light-and-shadows-using-gles2) -- Framedebugger now renders correctly when stepping through drawcalls. -- Cameras that request MSAA and Opaque Textures now use less frame bandwidth when they render. -- Fixed rendering in the gamma color space, so it doesn't appear darker. -- Particles SImple Lit and Particles Unlit Shaders now work correctly. -- __Soft Particles__ now work correctly. -- Camera fading for particles. -- Fixed a typo in the Unlit `IgnoreProjector` tag. -- Particles render in both eyes with stereo instancing -- Fixed specular issues on mobile. [case 1109017](https://issuetracker.unity3d.com/issues/scaled-objects-render-shadows-and-specularity-incorrectly-in-the-lwrp-on-device) -- Fixed issue causing LWRP to create MSAA framebuffer even when MSAA setting was disabled. -- Post-processing in mobile VR is now forced to be disabled. It was causing many rendering issues. -- Fixed Editor Previews breaking in Play Mode when VR is enabled. [Case 1109009](https://issuetracker.unity3d.com/issues/lwrp-editor-previews-break-in-play-mode-if-vr-is-enabled) -- A camera's HDR enable flag is now respected when rendering in XR. -- Terrain detail rendering now works correctly when LWRP is installed but inactive. - -## [5.2.0] - 2018-11-27 -### Added -- LWRP now handles blits that are required by the device when rendering to the backbuffer. -- You can now enable the SRP Batcher. To do so, go to the `Pipeline Asset`. Under `Advanced`, toggle `SRP Batcher`. - -### Changed -- Renamed shader variable `unity_LightIndicesOffsetAndCount` to `unity_PerObjectLightData`. -- Shader variables `unity_4LightIndices0` and `unity_4LightIndices1` are now declared as `unity_PerObjectLightIndices` array. - -## [5.1.0] - 2018-11-19 -### Added -- The user documentation for LWRP is now in this GitHub repo, instead of in the separate GitHub wiki. You can find the most up-to-date pages in the [TableOfContents.md](TableOfCotents.md) file. Pages not listed in that file are still in progress. - -### Changed -- The LWRP package is no longer in preview. -- LWRP built-in render passes are now internal. -- Changed namespace from `UnityEngine.Experimental.Rendering.LightweightPipeline` to `UnityEngine.Rendering.LWRP`. -- Changed namespace from `UnityEditor.Experimental.Rendering.LightweightPipeline` to `UnityEditor.Rendering.LWRP`. - -### Fixed -- LWRP now respects the iOS Player setting **Force hard shadows**. When you enable this setting, hardware filtering of shadows is disabled. -- Scene view mode now renders baked lightmaps correctly. [Case 1092227](https://issuetracker.unity3d.com/issues/lwrp-scene-view-modes-render-objects-black) -- Shadow bias calculations are now correct for both Shader Graph and Terrain shaders. -- Blit shader now ignores culling. -- When you select __Per Vertex__ option for __Additional Lights__, the __Per Object Limit__ option is not greyed out anymore. -- When you change camera viewport height to values above 1.0, the Unity Editor doesn't freeze anymore. [Case 1097497](https://issuetracker.unity3d.com/issues/macos-lwrp-editor-freezes-after-changing-cameras-viewport-rect-values) -- When you use AR with LWRP, the following error message is not displayed in the console anymore: "The camera list passed to the render pipeline is either null or empty." - -## [5.0.0-preview] - 2018-09-28 -### Added -- Added occlusion mesh rendering/hookup for VR -- You can now configure default depth and normal shadow bias values in the pipeline asset. -- You can now add the `LWRPAdditionalLightData` component to a `Light` to override the default depth and normal shadow bias. -- You can now log the amount of shader variants in your build. To do so, go to the `Pipeline Asset`. Under `Advanced`, select and set the `Shader Variant Log Level`. -### Changed -- Removed the `supportedShaderFeatures` property from LWRP core. The shader stripper now figures out which variants to strip based on the current assigned pipeline Asset in the Graphics settings. -### Fixed -- The following error does not appear in console anymore: ("Begin/End Profiler section mismatch") -- When you select a material with the Lit shader, this no longer causes the following error in the console: ("Material doesn't have..."). [case 1092354](https://fogbugz.unity3d.com/f/cases/1092354/) -- In the Simple Lit shader, per-vertex additional lights are now shaded properly. -- Shader variant stripping now works when you're building a Project with Cloud Build. This greatly reduces build times from Cloud Build. -- Dynamic Objects now receive lighting when the light mode is set to mixed. -- MSAA now works on Desktop platforms. -- The shadow bias value is now computed correctly for shadow cascades and different shadow resolutions. [case 1076285](https://issuetracker.unity3d.com/issues/lwrp-realtime-directional-light-shadow-maps-exhibit-artifacts) -- When you use __Area Light__ with LWRP, __Cast Shadows__ no longer overlaps with other UI elements in the Inspector. [case 1085363](https://issuetracker.unity3d.com/issues/inspector-area-light-cast-shadows-ui-option-is-obscured-by-render-mode-for-lwrp-regression-in-2018-dot-3a3) - -### Changed -Read/write XRGraphicsConfig -> Read-only XRGraphics interface to XRSettings. - -## [4.0.0-preview] - 2018-09-28 -### Added -- When you have enabled Gizmos, they now appear correctly in the Game view. -- Added requiresDepthPrepass field to RenderingData struct to tell if the runtime platform requires a depth prepass to generate a camera depth texture. -- The `RenderingData` struct now holds a reference to `CullResults`. -- When __HDR__ is enabled in the Camera but disabled in the Asset, an information box in the Camera Inspector informs you about it. -- When __MSAA__ is enabled in the Camera but disabled in the Asset, an information box in the Camera Inspector informs you about it. -- Enabled instancing on the terrain shader. -- Sorting of opaque objects now respects camera `opaqueSortMode` setting. -- Sorting of opaque objects disables front-to-back sorting flag, when camera settings allow that and the GPU has hidden surface removal. -- LWRP now has a Custom Light Explorer that suits its feature set. -- LWRP now supports Vertex Lit shaders for detail meshes on terrain. -- LWRP now has three interactive Autodesk shaders: Autodesk Interactive, Autodesk Interactive Masked and Autodesk Interactive Transparent. -- [Shader API] The `GetMainLight` and `GetAdditionalLight` functions can now compute shadow attenuation and store it in the new `shadowAttenuation` field in `LightData` struct. -- [Shader API] Added a `VertexPositionInputs` struct that contains vertex position in difference spaces (world, view, hclip). -- [Shader API] Added a `GetVertexPositionInputs` function to get an initialized `VertexPositionInputs`. -- [Shader API] Added a `GetPerObjectLightIndex` function to return the per-object index given a for-loop index. -- [Shader API] Added a `GetShadowCoord` function that takes a `VertexPositionInputs` as input. -- [ShaderLibrary] Added VertexNormalInputs struct that contains data for per-pixel normal computation. -- [ShaderLibrary] Added GetVertexNormalInputs function to return an initialized VertexNormalInputs. - -### Changed -- The `RenderingData` struct is now read-only. -- `ScriptableRenderer`always performs a Clear before calling `IRendererSetup::Setup.` -- `ScriptableRenderPass::Execute` no longer takes `CullResults` as input. Instead, use `RenderingData`as input, since that references `CullResults`. -- `IRendererSetup_Setup` no longer takes `ScriptableRenderContext` and `CullResults` as input. -- Shader includes are now referenced via package relative paths instead of via the deprecated shader export path mechanism https://docs.unity3d.com/2018.3/Documentation/ScriptReference/ShaderIncludePathAttribute.html. -- The LWRP Asset settings were re-organized to be more clear. -- Vertex lighting now controls if additional lights should be shaded per-vertex or per-pixel. -- Renamed all `Local Lights` nomenclature to `Additional Lights`. -- Changed shader naming to conform to our SRP shader code convention. -- [Shader API] Renamed `SpotAttenuation` function to `AngleAttenuation`. -- [Shader API] Renamed `_SHADOWS_ENABLED` keyword to `_MAIN_LIGHT_SHADOWS` -- [Shader API] Renamed `_SHADOWS_CASCADE` keyword to `_MAIN_LIGHT_SHADOWS_CASCADE` -- [Shader API] Renamed `_VERTEX_LIGHTS` keyword to `_ADDITIONAL_LIGHTS_VERTEX`. -- [Shader API] Renamed `_LOCAL_SHADOWS_ENABLED` to `_ADDITIONAL_LIGHT_SHADOWS` -- [Shader API] Renamed `GetLight` function to `GetAdditionalLight`. -- [Shader API] Renamed `GetPixelLightCount` function to `GetAdditionalLightsCount`. -- [Shader API] Renamed `attenuation` to `distanceAttenuation` in `LightData`. -- [Shader API] Renamed `GetLocalLightShadowStrength` function to `GetAdditionalLightShadowStrength`. -- [Shader API] Renamed `SampleScreenSpaceShadowMap` functions to `SampleScreenSpaceShadowmap`. -- [Shader API] Renamed `MainLightRealtimeShadowAttenuation` function to `MainLightRealtimeShadow`. -- [Shader API] Renamed light constants from `Directional` and `Local` to `MainLight` and `AdditionalLights`. -- [Shader API] Renamed `GetLocalLightShadowSamplingData` function to `GetAdditionalLightShadowSamplingData`. -- [Shader API] Removed OUTPUT_NORMAL macro. -- [Shader API] Removed `lightIndex` and `substractiveAttenuation` from `LightData`. -- [Shader API] Removed `ComputeShadowCoord` function. `GetShadowCoord` is provided instead. -- All `LightweightPipeline` references in API and classes are now named `LightweightRenderPipeline`. -- Files no longer have the `Lightweight` prefix. -- Renamed Physically Based shaders to `Lit`, `ParticlesLit`, and `TerrainLit`. -- Renamed Simple Lighting shaders to `SimpleLit`, and `ParticlesSimpleLit`. -- [ShaderLibrary] Renamed `InputSurfacePBR.hlsl`, `InputSurfaceSimple.hlsl`, and `InputSurfaceUnlit` to `LitInput.hlsl`, `SimpleLitInput.hlsl`, and `UnlitInput.hlsl`. These files were moved from the `ShaderLibrary` folder to the`Shaders`. -- [ShaderLibrary] Renamed `LightweightPassLit.hlsl` and `LightweightPassLitSimple.hlsl` to `LitForwardPass.hlsl` and `SimpleLitForwardPass.hlsl`. These files were moved from the `ShaderLibrary` folder to `Shaders`. -- [ShaderLibrary] Renamed `LightweightPassMetaPBR.hlsl`, `LightweightPassMetaSimple.hlsl` and `LighweightPassMetaUnlit` to `LitMetaPass.hlsl`, `SimpleLitMetaPass.hlsl` and `UnlitMetaPass.hlsl`. These files were moved from the `ShaderLibrary` folder to `Shaders`. -- [ShaderLibrary] Renamed `LightweightPassShadow.hlsl` to `ShadowCasterPass.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `LightweightPassDepthOnly.hlsl` to `DepthOnlyPass.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `InputSurfaceTerrain.hlsl` to `TerrainLitInput.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `LightweightPassLitTerrain.hlsl` to `TerrainLitPases.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `ParticlesPBR.hlsl` to `ParticlesLitInput.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `InputSurfacePBR.hlsl` to `LitInput.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `InputSurfaceUnlit.hlsl` to `UnlitInput.hlsl`. This file was moved to the `Shaders` folder. -- [ShaderLibrary] Renamed `InputBuiltin.hlsl` to `UnityInput.hlsl`. -- [ShaderLibrary] Renamed `LightweightPassMetaCommon.hlsl` to `MetaInput.hlsl`. -- [ShaderLibrary] Renamed `InputSurfaceCommon.hlsl` to `SurfaceInput.hlsl`. -- [ShaderLibrary] Removed LightInput struct and GetLightDirectionAndAttenuation. Use GetAdditionalLight function instead. -- [ShaderLibrary] Removed ApplyFog and ApplyFogColor functions. Use MixFog and MixFogColor instead. -- [ShaderLibrary] Removed TangentWorldToNormal function. Use TransformTangentToWorld instead. -- [ShaderLibrary] Removed view direction normalization functions. View direction should always be normalized per pixel for accurate results. -- [ShaderLibrary] Renamed FragmentNormalWS function to NormalizeNormalPerPixel. - -### Fixed -- If you have more than 16 lights in a scene, LWRP no longer causes random glitches while rendering lights. -- The Unlit shader now samples Global Illumination correctly. -- The Inspector window for the Unlit shader now displays correctly. -- Reduced GC pressure by removing several per-frame memory allocations. -- The tooltip for the the camera __MSAA__ property now appears correctly. -- Fixed multiple C# code analysis rule violations. -- The fullscreen mesh is no longer recreated upon every call to `ScriptableRenderer.fullscreenMesh`. - -## [3.3.0-preview] - 2018-01-01 -### Added -- Added callbacks to LWRP that can be attached to a camera (IBeforeCameraRender, IAfterDepthPrePass, IAfterOpaquePass, IAfterOpaquePostProcess, IAfterSkyboxPass, IAfterTransparentPass, IAfterRender) - -###Changed -- Clean up LWRP creation of render textures. If we are not going straight to screen ensure that we create both depth and color targets. -- UNITY_DECLARE_FRAMEBUFFER_INPUT and UNITY_READ_FRAMEBUFFER_INPUT macros were added. They are necessary for reading transient attachments. -- UNITY_MATRIX_I_VP is now defined. -- Renamed LightweightForwardRenderer to ScriptableRenderer. -- Moved all light constants to _LightBuffer CBUFFER. Now _PerCamera CBUFFER contains all other per camera constants. -- Change real-time attenuation to inverse square. -- Change attenuation for baked GI to inverse square, to match real-time attenuation. -- Small optimization in light attenuation shader code. - -### Fixed -- Lightweight Unlit shader UI doesn't throw an error about missing receive shadow property anymore. - -## [3.2.0-preview] - 2018-01-01 -### Changed -- Receive Shadows property is now exposed in the material instead of in the renderer. -- The UI for Lightweight asset has been updated with new categories. A more clean structure and foldouts has been added to keep things organized. - -### Fixed -- Shadow casters are now properly culled per cascade. (case 1059142) -- Rendering no longer breaks when Android platform is selected in Build Settings. (case 1058812) -- Scriptable passes no longer have missing material references. Now they access cached materials in the renderer.(case 1061353) -- When you change a Shadow Cascade option in the Pipeline Asset, this no longer warns you that you've exceeded the array size for the _WorldToShadow property. -- Terrain shader optimizations. - -## [3.1.0-preview] - 2018-01-01 - -### Fixed -- Fixed assert errors caused by multi spot lights -- Fixed LWRP-DirectionalShadowConstantBuffer params setting - -## [3.0.0-preview] - 2018-01-01 -### Added -- Added camera additional data component to control shadows, depth and color texture. -- pipeline now uses XRSEttings.eyeTextureResolutionScale as renderScale when in XR. -- New pass architecture. Allows for custom passes to be written and then used on a per camera basis in LWRP - -### Changed -- Shadow rendering has been optimized for the Mali Utgard architecture by removing indexing and avoiding divisions for orthographic projections. This reduces the frame time by 25% on the Overdraw benchmark. -- Removed 7x7 tent filtering when using cascades. -- Screenspace shadow resolve is now only done when rendering shadow cascades. -- Updated the UI for the Lighweight pipeline asset. -- Update assembly definitions to output assemblies that match Unity naming convention (Unity.*). - -### Fixed -- Post-processing now works with VR on PC. -- PS4 compiler error -- Fixed VR multiview rendering by forcing MSAA to be off. There's a current issue in engine that breaks MSAA and Texture2DArray. -- Fixed UnityPerDraw CB layout -- GLCore compute buffer compiler error -- Occlusion strength not being applied on LW standard shaders -- CopyDepth pass is being called even when a depth from prepass is available -- GLES2 shader compiler error in IntegrationTests -- Can't set RenderScale and ShadowDistance by script -- VR Single Pass Instancing shadows -- Fixed compilation errors on Nintendo Switch (limited XRSetting support). - -## [2.0.0-preview] - 2018-01-01 - -### Added -- Explicit render target load/store actions were added to improve tile utilization -- Camera opaque color can be requested on the pipeline asset. It can be accessed in the shader by defining a _CameraOpaqueTexture. This can be used as an alternative to GrabPass. -- Dynamic Batching can be enabled in the pipeline asset -- Pipeline now strips unused or invalid variants and passes based on selected pipeline capabilities in the asset. This reduces build and memory consuption on target. -- Shader stripping settings were added to pipeline asset - -### Changed -#### Pipeline -- Pipeline code is now more modular and extensible. A ForwardRenderer class is initialized by the pipeline with RenderingData and it's responsible for enqueueing and executing passes. In the future pluggable renderers will be supported. -- On mobile 1 directional light + up to 4 local lights (point or spot) are computed -- On other platforms 1 directional light + up to 8 local lights are computed -- Multiple shadow casting lights are supported. Currently only 1 directional + 4 spots light shadows. -#### Shading Framework -- Directional Lights are always considered a main light in shader. They have a fast shading path with no branching and no indexing. -- GetMainLight() is provided in shader to initialize Light struct with main light shading data. -- Directional lights have a dedicated shadowmap for performance reasons. Shadow coord always comes from interpolator. -- MainLigthRealtimeShadowAttenuation(float4 shadowCoord) is provided to compute main light realtime shadows. -- Spot and Point lights are always shaded in the light loop. Branching on uniform and indexing happens when shading them. -- GetLight(half index, float3 positionWS) is provided in shader to initialize Light struct for spot and point lights. -- Spot light shadows are baked into a single shadow atlas. -- Shadow coord for spot lights is always computed on fragment. -- Use LocalLightShadowAttenuation(int lightIndex, float3 positionWS) to comppute realtime shadows for spot lights. - -### Fixed -- Issue that was causing VR on Android to render black -- Camera viewport issues -- UWP build issues -- Prevent nested camera rendering in the pipeline - -## [1.1.4-preview] - 2018-01-01 - -### Added - - Terrain and grass shaders ported - - Updated materials and shader default albedo and specular color to midgrey. - - Exposed _ScaledScreenParams to shader. It works the same as _ScreenParams but takes pipeline RenderScale into consideration - - Performance Improvements in mobile - -### Fixed - - SRP Shader library issue that was causing all constants to be highp in mobile - - shader error that prevented LWRP to build to UWP - - shader compilation errors in Linux due to case sensitive includes - - Rendering Texture flipping issue - - Standard Particles shader cutout and blending modes - - crash caused by using projectors - - issue that was causing Shadow Strength to not be computed on mobile - - Material Upgrader issue that caused editor to SoftLocks - - GI in Unlit shader - - Null reference in the Unlit material shader GUI - -## [1.1.2-preview] - 2018-01-01 - -### Changed - - Performance improvements in mobile - -### Fixed - - Shadows on GLES 2.0 - - CPU performance regression in shadow rendering - - Alpha clip shadow issues - - Unmatched command buffer error message - - Null reference exception caused by missing resource in LWRP - - Issue that was causing Camera clear flags was being ignored in mobile - - -## [1.1.1-preview] - 2018-01-01 - -### Added - - Added Cascade Split selection UI - - Added SHADER_HINT_NICE_QUALITY. If user defines this to 1 in the shader Lightweight pipeline will favor quality even on mobile platforms. - -### Changed - - Shadowmap uses 16bit format instead of 32bit. - - Small shader performance improvements - -### Fixed - - Subtractive Mode - - Shadow Distance does not accept negative values anymore - - -## [0.1.24] - 2018-01-01 - -### Added - - Added Light abstraction layer on lightweight shader library. - - Added HDR global setting on pipeline asset. - - Added Soft Particles settings on pipeline asset. - - Ported particles shaders to SRP library - -### Changed - - HDR RT now uses what format is configured in Tier settings. - - Refactored lightweight standard shaders and shader library to improve ease of use. - - Optimized tile LOAD op on mobile. - - Reduced GC pressure - - Reduced shader variant count by ~56% by improving fog and lightmap keywords - - Converted LW shader library files to use real/half when necessary. - -### Fixed - - Realtime shadows on OpenGL - - Shader compiler errors in GLES 2.0 - - Issue sorting issues when BeforeTransparent custom fx was enabled. - - VR single pass rendering. - - Viewport rendering issues when rendering to backbuffer. - - Viewport rendering issues when rendering to with MSAA turned off. - - Multi-camera rendering. - -## [0.1.23] - 2018-01-01 - -### Added - - UI Improvements (Rendering features not supported by LW are hidden) - -### Changed - - Shaders were ported to the new SRP shader library. - - Constant Buffer refactor to use new Batcher - - Shadow filtering and bias improved. - - Pipeline now updates color constants in gamma when in Gamma colorspace. - - Optimized ALU and CB usage on Shadows. - - Reduced shader variant count by ~33% by improving shadow and light classification keywords - - Default resources were removed from the pipeline asset. - -### Fixed - - Fixed shader include path when using SRP from package manager. - - Fixed spot light attenuation to match Unity Built-in pipeline. - - Fixed depth pre-pass clearing issue. - -## [0.1.12] - 2018-01-01 - -### Added - - Standard Unlit shader now has an option to sample GI. - - Added Material Upgrader for stock Unity Mobile and Legacy Shaders. - - UI improvements - -### Changed -- Realtime shadow filtering was improved. - -### Fixed - - Fixed an issue that was including unreferenced shaders in the build. - - Fixed a null reference caused by Particle System component lights. +# Changelog +All notable changes to this package will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [12.1.1] - 2021-10-04 + +### Changed + +- Main light shadow, additional light shadow and additional light keywords are now enabled based on urp setting instead of existence in scene. This allows better variant stripping. + +### Fixed +- Fixed a regression bug where XR camera postion can not be modified in beginCameraRendering [case 1365000] +- Fix for rendering thumbnails. [case 1348209](https://issuetracker.unity3d.com/issues/preview-of-assets-do-not-show-in-the-project-window) +- Fixed ShaderGraph needing updated normals for ShadowCaster in URP. +- Added "Conservative Enclosing Sphere" setting to fix shadow frustum culling issue where shadows are erroneously culled in corners of cascades [case 1153151](https://issuetracker.unity3d.com/issues/lwrp-shadows-are-being-culled-incorrectly-in-the-corner-of-the-camera-viewport-when-the-far-clip-plane-is-small) +- Fixed an issue where screen space shadows has flickering with deferred mode [case 1354681](https://issuetracker.unity3d.com/issues/screen-space-shadows-flicker-in-scene-view-when-using-deferred-rendering) + +## [12.1.0] - 2021-09-23 + +### Added +- URP global setting for stripping post processing shader variants. +- URP global setting for stripping off shader variants. + +### Changed +- URP will no longer render via an intermediate texture unless actively required by a Renderer Feature. See the upgrade guide for compatibility options and how assets are upgraded. + + +### Fixed +- Fixed a Universal Targets in ShaderGraph not rendering correctly in game view [1352225] +- MaterialReimporter.ReimportAllMaterials and MaterialReimporter.ReimportAllHDShaderGraphs now batch the asset database changes to improve performance. + +## [12.0.0] - 2021-01-11 +### Added +- Added support for default sprite mask shaders for the 2D Renderer in URP. +- Added View Vector node to mimic old behavior of View Direction node in URP. +- Added support for the PlayStation 5 platform. +- Enabled deferred renderer in UI. +- Added support for light layers, which uses Rendering Layer Masks to make Lights in your Scene only light up specific Meshes. +- 2D Light Texture Node. A Shader Graph node that enable sampling of the Light Textures generated by the 2D Renderer in a lit scene. +- Fixed an error where multisampled texture being bound to a non-multisampled sampler in XR. [case 1297013](https://issuetracker.unity3d.com/issues/android-urp-black-screen-when-building-project-to-an-android-device-with-mock-hmd-enabled-and-multisampled-sampler-errors) +- Added _SURFACE_TYPE_TRANSPARENT keyword to URP shaders. +- Added Depth and DepthNormals passes to particles shaders. +- Added support for SSAO in Particle and Unlit shaders. +- Added Decal support. This includes new Decal Projector component, Decal renderer feature and Decal shader graph. +- Added a SpeedTree 8 Shader Graph but did not set it as the default when importing or upgrading Speed Tree 8 assets. Because URP doesn't yet support per-material culling, this Shader Graph does not yet behave in the same way as the existing handwritten SpeedTree 8 shader for URP. +- Added optional Depth Priming. Allows the forward opaque pass of the base camera to skip shading certain fragments if they don't contribute to the final opaque output. +- Added blending and box projection for reflection probes. +- Added 'Store Actions' option that enables bandwidth optimizations on mobile GPU architectures. +- Added "Allow Material Override" option to Lit and Unlit ShaderGraph targets. When checked, allows Material to control the surface options (transparent/opaque, blend mode, etc). +- Added a new UI for Render Pipeline Converters. Used now for Built-in to Universal conversion. +- Added sections on Light Inspector. +- Reorder camera inspector to be in the same order as HDRP. +- Added new URP Debug Views under Window/Analysis/Rendering Debugger. +- Added support for controlling Volume Framework Update Frequency in UI on Cameras and URP Asset as well as through scripting. +- Added URP Global Settings Asset to the Graphics Settings - a common place for project-wide URP settings. +- Added possibility to rename light layer values. +- Added Light cookies support to directional, point and spot light. Directional light cookie is main light only feature. +- Added GetUniversalAdditionalLightData, a method that returns the additional data component for a given light or create one if it doesn't exist yet. +- VFX: Basic support of Lit output. +- Added Motion Vector render pass for URP. +- VFX: Fix light cookies integration. +- Added Lights 2D to the Light Explorer window. +- Two new URP specific scene templates, Basic which has a camera and directional light, then Standard which has the addition of a global volume with basic post effects setup. +- Added Render Settings Converter to the Render Pipeline Converter, this tool creates and assigns URP Assets based off rendering settings of a Builtin project. +- XR: Added Late Latching support to reduce VR latency (Quest). +- Fixed incorrect shadow fade in deferred rendering mode. +- Added a help button on material editor to show the shader documentation page + +### Changed +- Moved fog evaluation from vertex shader to pixel shader. This improves rendering of fog for big triangles and fog quality. This can change the look of the fog slightly. +- UNITY_Z_0_FAR_FROM_CLIPSPACE now remaps to [0, far] range on all platforms consistently. Previously OpenGL platforms did not remap, discarding small amount of range [-near, 0]. +- Moved all 2D APIs out of experimental namespace. +- ClearFlag.Depth does not implicitely clear stencil anymore. ClearFlag.Stencil added. +- The Forward Renderer asset is renamed to the Universal Renderer asset. The Universal Renderer asset contains the property Rendering Path that lets you select the Forward or the Deferred Rendering Path. +- Improved PixelPerfectCamera UI/UX +- Changed Pixel Snapping and Upscale Render Texture in the PixelPerfectCamera to a dropdown. +- Move Assets/Create/Rendering/Universal Render Pipeline/Pipeline Asset (2D Renderer) to Assets/Create/Rendering/URP Asset (with 2D Renderer) +- Move Assets/Create/Rendering/Universal Render Pipeline/2D Renderer to Assets/Create/Rendering/URP 2D Renderer +- Move Assets/Create/Rendering/Universal Render Pipeline/Renderer Feature to Assets/Create/Rendering/URP Renderer Feature +- Move Assets/Create/Rendering/Universal Render Pipeline/Post-process Data to Assets/Create/Rendering/URP Post-process Data +- Move Assets/Create/Rendering/Universal Render Pipeline/Pipeline Asset (Forward Renderer) to Assets/Create/Rendering/URP Asset (with Forward Renderer) +- Move Assets/Create/Rendering/Universal Render Pipeline/XR System Data to Assets/Create/Rendering/URP XR System Data +- Move Assets/Create/Rendering/Universal Render Pipeline/Forward Renderer to Assets/Create/Rendering/URP Forward Renderer +- Removing unused temporary depth buffers for Depth of Field and Panini Projection. +- Optimized the Bokeh Depth of Field shader on mobile by using half precision floats. +- Changed UniversalRenderPipelineCameraEditor to URPCameraEditor +- Made 2D shadow casting more efficient +- Reduced the size of the fragment input struct of the TerrainLitPasses and LitGBufferPass, SimpleLitForwardPass and SimpleLitGBufferPass lighting shaders. +- Bokeh Depth of Field performance improvement: moved some calculations from GPU to CPU. +- Advanced Options > Priority has been renamed to Sorting Priority +- Opacity as Density blending feature for Terrain Lit Shader is now disabled when the Terrain has more than four Terrain Layers. This is now similar to the Height-blend feature for the Terrain Lit Shader. +- DepthNormals passes now sample normal maps if used on the material, otherwise output the geometry normal. +- SSAO Texture is now R8 instead of ARGB32 if supported by the platform. +- Enabled subsurface scattering with GI on handwritten Universal ST8 shader. +- Material upgrader now also upgrades AnimationClips in the project that have curves bound to renamed material properties. +- 2D Lights now inherit from Light2DBase. +- The behavior of setting a camera's Background Type to "Dont Care" has changed on mobile. Previously, "Dont Care" would behave identically to "Solid Color" on mobile. Now, "Dont Care" corresponds to the render target being filled with arbitrary data at the beginning of the frame, which may be faster in some situations. Note that there are no guarantees for the exact content of the render target, so projects should use "Dont care" only if they are guaranteed to render to, or otherwise write every pixel every frame. +- Stripping shader variants per renderer features instead of combined renderer features. +- When MSAA is enabled and a depth texture is required, the opaque pass depth will be copied instead of scheduling a depth prepass. +- URP Asset Inspector - Advanced settings have been reordered under `Show Additional Properties` on each section. +- Changed the default name when a new urp asset is created. +- URP Asset Inspector - `General` section has been renamed to `Rendering`. +- Refactored some of the array resizing code around decal projector rendering to use new APIs in render core +- UniversalRendererData and ForwardRendererData GUIDs have been reversed so that users coming from 2019LTS, 2020LTS and 2021.1 have a smooth upgrade path, you may encounter issues coming from 2021.2 Alpha/Beta versions and are recommended to start with a fresh library if initial upgrade fails. +- VFX: New shadergraph support directly on Universal target. + +### Fixed +- Fixed an issue in PostProcessPass causing OnGUI draws to not show on screen. [case 1346650] +- Fixed an issue with the blend mode in Sprite-Lit-Default shader causing alpha to overwrite the framebuffer. [case 1331392](https://issuetracker.unity3d.com/product/unity/issues/guid/1331392/) +- Fixed pixel perfect camera rect not being correctly initialized. [case 1312646](https://issuetracker.unity3d.com/product/unity/issues/guid/1312646/) +- Camera Inspector Stack list edition fixes. +- Fix indentation of Emission map on material editor. +- Fixed additional camera data help url +- Fixed additional light data help url +- Fixed Opacity as Density blending artifacts on Terrain that that caused Terrain to have modified splat weights of zero in some areas and greater than one in others. [case 1283124](https://issuetracker.unity3d.com/product/unity/issues/guid/1283124/) +- Fixed an issue where Sprite type Light2Ds would throw an exeception if missing a sprite +- Fixed an issue where Sprite type Light2Ds were missing a default sprite +- Fixed an issue where ShadowCasters were sometimes being rendered twice in the editor while in playmode. +- Fixed an issue where ShadowCaster2D was generating garbage when running in the editor. [case 1304158](https://issuetracker.unity3d.com/product/unity/issues/guid/1304158/) +- Fixed an issue where the 2D Renderer was not rendering depth and stencil in the normal rendering pass +- Fixed an issue where 2D lighting was incorrectly calculated when using a perspective camera. +- Fixed an issue where objects in motion might jitter when the Pixel Perfect Camera is used. [case 1300474](https://issuetracker.unity3d.com/issues/urp-characters-sprite-repeats-in-the-build-when-using-pixel-perfect-camera-and-2d-renderer) +- Fixed an issue where filtering in the scene view would not properly highlight the filtered objects. case 1324359 +- Fixed an issue where the scene view camera was not correctly cleared for the 2D Renderer. [case 1311377](https://issuetracker.unity3d.com/product/unity/issues/guid/1311377/) +- Fixed an issue where the letter box/pillar box areas were not properly cleared when the Pixel Perfect Camera is used. [case 1291224](https://issuetracker.unity3d.com/issues/pixel-perfect-image-artifact-appear-between-the-reference-resolution-and-screen-resolution-borders-when-strech-fill-is-enabled) +- Fixed an issue where the Cinemachine Pixel Perfect Extension might cause the Orthographic Size of the Camera to jump to 1 when the Scene is loaded. [case 1249076](https://issuetracker.unity3d.com/issues/cinemachine-pixel-perfect-camera-extension-causes-the-orthogonal-size-to-jump-to-1-when-the-scene-is-loaded) +- Fixed an issue where 2D Shadows were casting to the wrong layers [case 1300753][https://issuetracker.unity3d.com/product/unity/issues/guid/1300753/] +- Fixed an issue where Light2D did not upgrade Shadow Strength, Volumetric Intensity, Volumetric Shadow Strength correctly [case 1317755](https://issuetracker.unity3d.com/issues/urp-lighting-missing-orange-tint-in-scene-background) +- Fixed an issue where render scale was breaking SSAO in scene view. [case 1296710](https://issuetracker.unity3d.com/issues/ssao-effect-floating-in-the-air-in-scene-view-when-2-objects-with-shadergraph-materials-are-on-top-of-each-other) +- Fixed GC allocations from XR occlusion mesh when using multipass. +- SMAA post-filter only clear stencil buffer instead of depth and stencil buffers. +- Fixed an issue where the inspector of Renderer Data would break after adding RenderObjects renderer feature and then adding another renderer feature. +- Fixed an issue where soft particles did not work with orthographic projection. [case 1294607](https://issuetracker.unity3d.com/product/unity/issues/guid/1294607/) +- Fixed wrong shader / properties assignement to materials created from 3DsMax 2021 Physical Material. (case 1293576) +- Normalized the view direction in Shader Graph to be consistent across Scriptable Render Pieplines. +- Fixed material upgrader to run in batch mode [case 1305402] +- Fixed gizmos drawing in game view. [case 1302504](https://issuetracker.unity3d.com/issues/urp-handles-with-set-ztest-do-not-respect-depth-sorting-in-the-game-view) +- Fixed an issue in shaderGraph target where the ShaderPass.hlsl was being included after SHADERPASS was defined +- Fixed base camera to keep render texture in sync with camera stacks. [case 1288105](https://issuetracker.unity3d.com/issues/srp-base-camera-rendering-to-render-texture-takes-overlay-camera-into-account-but-not-its-canvas) +- Fixed base camera to keep viewport in sync with camera stacks. [case 1311268](https://issuetracker.unity3d.com/issues/buttons-clickable-area-is-offset-when-canvas-render-camera-is-an-overlay-camera-and-viewport-rect-is-changed-on-base-camera) +- Fixed base camera to keep display index in sync with camera stacks. [case 1252265](https://issuetracker.unity3d.com/issues/universal-rp-overlay-camera-still-renders-to-displaya) +- Fixed base camera to keep display index in sync with camera stacks for canvas. [case 1291872](https://issuetracker.unity3d.com/issues/canvas-renders-only-on-the-display-1-when-its-set-to-screen-space-camera-or-world-space-and-has-overlay-type-camera-assigned) +- Fixed render pass reusage with camera stack on vulkan. [case 1226940](https://issuetracker.unity3d.com/issues/vulkan-each-camera-stack-layer-generate-a-render-pass-separately-when-render-pass-are-the-same) +- Fixed camera stack UI correctly work with prefabs. [case 1308717](https://issuetracker.unity3d.com/issues/the-prefab-apply-slash-revert-menu-cant-be-opened-by-right-clicking-on-the-stack-label-under-the-camera-component-in-the-inspector) +- Fixed an issue where Particle Lit shader had an incorrect fallback shader [case 1312459] +- Fixed an issue with backbuffer MSAA on Vulkan desktop platforms. +- Fixed shadow cascade blend culling factor. +- Fixed remove of the Additional Light Data when removing the Light Component. +- Fixed remove of the Additional Camera Data when removing the Camera Component. +- Fixed shadowCoord error when main light shadow defined in unlit shader graph [case 1175274](https://issuetracker.unity3d.com/issues/shadows-not-applying-when-using-file-in-a-custom-function-node-with-universal-rp) +- Removed Custom.meta which was causing warnings. [case 1314288](https://issuetracker.unity3d.com/issues/urp-warnings-about-missing-metadata-appear-after-installing) +- Fixed a case where shadow fade was clipped too early. +- Fixed an issue where SmoothnessSource would be upgraded to the wrong value in the material upgrader. +- Fixed multi editing of Bias property on lights. [case 1289620] +- Fixed an issue where bokeh dof is applied incorrectly when there is an overlay camera in the camera stack. [case 1303572](https://issuetracker.unity3d.com/issues/urp-bokeh-depth-of-field-is-applied-incorrectly-when-the-main-camera-has-an-overlay-camera-in-the-camera-stack) +- Fixed SafeNormalize returning invalid vector when using half with zero length. [case 1315956] +- Fixed lit shader property duplication issue. [case 1315032](https://issuetracker.unity3d.com/issues/shader-dot-propertytoid-returns-the-same-id-when-shaders-properties-have-the-same-name-but-different-type) +- Fixed undo issues for the additional light property on the UniversalRenderPipeline Asset. [case 1300367] +- Fixed an issue where SSAO would sometimes not render with a recently imported renderer. +- Fixed a regression where the precision was changed. [case 1313942](https://issuetracker.unity3d.com/issues/urp-shader-precision-is-reduced-to-half-when-scriptablerenderfeature-class-is-in-the-project) +- Fixed an issue where motion blur would allocate memory each frame. [case 1314613](https://issuetracker.unity3d.com/issues/urp-gc-alloc-increases-when-motion-blur-override-is-enabled-with-intensity-set-above-0) +- Fixed an issue where using Camera.targetTexture with Linear Color Space on an Android device that does not support sRGB backbuffer results in a RenderTexture that is too bright. [case 1307710] +- Fixed issue causing missing shaders on DirectX 11 feature level 10 GPUs. [case 1278390](https://issuetracker.unity3d.com/product/unity/issues/guid/1278390/) +- Fixed errors when the Profiler is used with XR multipass. [case 1313141](https://issuetracker.unity3d.com/issues/xr-urp-profiler-spams-errors-in-the-console-upon-entering-play-mode) +- Fixed materials being constantly dirty. +- Fixed double sided and clear coat multi editing shader. +- Fixed issue where copy depth depth pass for gizmos was being skipped in game view [case 1302504](https://issuetracker.unity3d.com/issues/urp-handles-with-set-ztest-do-not-respect-depth-sorting-in-the-game-view) +- Fixed an issue where transparent objects sampled SSAO. +- Fixed an issue where Depth Prepass was not run when SSAO was set to Depth Mode. +- Fixed an issue where changing camera's position in the BeginCameraRendering do not apply properly. [case 1318629] (https://issuetracker.unity3d.com/issues/camera-doesnt-move-when-changing-its-position-in-the-begincamerarendering-and-the-endcamerarendering-methods) +- Fixed depth of field pass usage on unsupported devices. [case 1327076](https://issuetracker.unity3d.com/issues/adreno-3xx-nothing-is-rendered-when-post-processing-is-enabled) +- Fixed an issue where SMAA did not work for OpenGL [case 1318214](https://issuetracker.unity3d.com/issues/urp-there-is-no-effect-when-using-smaa-in-urp-with-opengles-api) +- Fixed an issue with Shader Graph Lit shaders where the normalized view direction produced incorrect lighting. [1332804] +- Fixed return values from GetStereoProjectionMatrix() and SetStereoViewMatrix(). [case 1312813](https://issuetracker.unity3d.com/issues/xr-urp-begincamerarender-method-is-lagging-behind-when-using-urp) +- Fixed CopyDepthPass incorrectly always enqueued when deferred rendering mode was enabled when it should depends on the pipeline asset settings. +- Fixed renderer post processing option to work with asset selector re-assing. [case 1319454](https://issuetracker.unity3d.com/issues/urp-universal-renderer-post-processing-doesnt-enable-when-postprocessdata-reassigned-from-the-asset-selector-window) +- Fixed post processing to be enabled by default in the renderer when creating URP asset option. [case 1333461](https://issuetracker.unity3d.com/issues/post-processing-is-disabled-by-default-in-the-forward-renderer-when-creating-a-new-urp-asset) +- Fixed shaderGraph shaders to render into correct depthNormals passes when deferred rendering mode and SSAO are enabled. +- Fixed ordering of subshaders in the Unlit Shader Graph, such that shader target 4.5 takes priority over 2.0. [case 1328636](https://issuetracker.unity3d.com/product/unity/issues/guid/1328636/) +- Fixed issue where it will clear camera color if post processing is happening on XR [case 1324451] +- Fixed a case where camera dimension can be zero. [case 1321168](https://issuetracker.unity3d.com/issues/urp-attempting-to-get-camera-relative-temporary-rendertexture-is-thrown-when-tweening-the-viewport-rect-values-of-a-camera) +- Fixed renderer creation in playmode to have its property reloaded. [case 1333463] +- Fixed gizmos no longer allocate memory in game view. [case 1328852] +- Fixed an issue where shadow artefacts appeared between cascades on Terrain Detail objects. +- Fixed ShaderGraph materials to select render queue in the same way as handwritten shader materials by default, but allows for a user override for custom behavior. [case 1335795] +- Fixed sceneview debug mode rendering (case 1211436). +- URP Global Settings can now be unassigned in the Graphics tab (case 1343570). +- VFX: Fixed soft particles when HDR or Opaque texture isn't enabled +- VFX: Fixed OpenGL soft particles fallback when depth texture isn't available +- Fixed soft shadows shader variants not set to multi_compile_fragment on some shaders (gbuffer pass, speedtree shaders, WavingGrass shader). +- Fixed issue with legacy stereo matrices with XR multipass. [case 1342416] +- Fixed unlit shader function name ambiguity +- Fixed Terrain holes not appearing in shadows [case 1349305] +- VFX: Compilation issue with ShaderGraph and planar lit outputs [case 1349894](https://issuetracker.unity3d.com/product/unity/issues/guid/1349894/) +- Fixed an issue where TerrainLit was rendering color lighter than Lit [case 1340751] (https://issuetracker.unity3d.com/product/unity/issues/guid/1340751/) +- Fixed Camera rendering when capture action and post processing present. [case 1350313] +- Fixed artifacts in Speed Tree 8 billboard LODs due to SpeedTree LOD smoothing/crossfading [case 1348407] +- Fix sporadic NaN when using normal maps with XYZ-encoding [case 1351020](https://issuetracker.unity3d.com/issues/android-urp-vulkan-nan-pixels-and-bloom-post-processing-generates-visual-artifacts) +- Support undo of URP Global Settings asset assignation (case 1342987). +- Removed unsupported fields from Presets of Light and Camera [case 1335979]. +- Fixed graphical artefact when terrain height map is used with rendering layer mask for lighting. +- Fixed an issue where _AfterPostProcessTexture was no longer being assigned in UniversalRenderer. +- Fixed UniversalRenderPipelineAsset now being able to use multiedit +- Fixed memory leak with XR combined occlusion meshes. [case 1366173] + +### Changed +- Change Asset/Create/Shader/Universal Render Pipeline/Lit Shader Graph to Asset/Create/Shader Graph/URP/Lit Shader Graph +- Change Asset/Create/Shader/Universal Render Pipeline/Sprite Lit Shader Graph to Asset/Create/Shader Graph/URP/Sprite Lit Shader Graph +- Change Asset/Create/Shader/Universal Render Pipeline/Unlit Shader Graph to Asset/Create/Shader Graph/URP/Unlit Shader Graph +- Change Asset/Create/Shader/Universal Render Pipeline/Sprite Unlit Shader Graph to Asset/Create/Shader Graph/URP/Sprite Unlit Shader Graph +- Moved Edit/Render Pipeline/Universal Render Pipeline/Upgrade Project Materials to 2D Renderer Materials to Edit/Rendering/Materials/Convert All Built-in Materials to URP 2D Renderer +- Moved Edit/Render Pipeline/Universal Render Pipeline/Upgrade Scene Materials to 2D Renderer Materials to Edit/Rendering/Materials/Convert All Built-in Scene Materials to URP 2D Renderer +- Moved Edit/Render Pipeline/Universal Render Pipeline/Upgrade Project URP Parametric Lights to Freeform to Edit/Rendering/Lights/Convert Project URP Parametric Lights to Freeform +- Moved Edit/Render Pipeline/Universal Render Pipeline/Upgrade Scene URP Parametric Lights to Freeform to Edit/Rendering/Lights/Convert Scene URP Parametric Lights to Freeform +- Moved Edit/Render Pipeline/Universal Render Pipeline/Upgrade Project Materials to URP Materials to Edit/Rendering/Materials/Convert All Built-in Materials to URP +- Moved Edit/Render Pipeline/Universal Render Pipeline/Upgrade Selected Materials to URP Materials to Edit/Rendering/Materials/Convert Selected Built-in Materials to URP +- Deprecated GetShadowFade in Shadows.hlsl, use GetMainLightShadowFade or GetAdditionalLightShadowFade. +- Improved shadow cascade GUI drawing with pixel perfect, hover and focus functionalities. +- Shadow fade now uses border value for calculating shadow fade distance and fall off linearly. +- Improved URP profiling scopes. Remove low impact scopes from the command buffer for a small performance gain. Fix the name and invalid scope for context.submit() scope. Change the default profiling name of ScriptableRenderPass to Unnamed_ScriptableRenderPass. +- Using the same MaterialHeaderScope for material editor as HDRP is using + +### Removed +- Code to upgrade from LWRP to URP was removed. This means if you want to upgrade from LWRP you must first upgrade to previous versions of URP and then upgrade to this version. + +## [11.0.0] - 2020-10-21 +### Added +- Added real-time Point Light Shadows. +- Added a supported MSAA samples count check, so the actual supported MSAA samples count value can be assigned to RenderTexture descriptors. +- Added the TerrainCompatible SubShader Tag. Use this Tag in your custom shader to tell Unity that the shader is compatible with the Terrain system. +- Added _CameraSortingLayerTexture global shader variable and related parameters +- Added preset shapes for creating a freeform light +- Added serialization of Freeform ShapeLight mesh to avoid CPU cost of generating them on the runtime. +- Added 2D Renderer Asset Preset for creating a Universal Renderer Asset +- Added an option to use faster, but less accurate approximation functions when converting between the sRGB and Linear color spaces. +- Added screen space shadow as renderer feature +- Added [DisallowMultipleRendererFeature] attribute for Renderer Features. +- Added support for Enlighten precomputed realtime Global Illumination. + +### Changed +- Optimized 2D Renderer performance on mobile GPUs by reducing the number of render target switches. +- Optimized 2D Renderer performance by rendering the normal buffer at the same lower resolution as the light buffers. +- Improved Light2D UI/UX +- Improved 2D Menu layout +- Deprecated Light2D Parametric Light +- Deprecated Light2D point light cookie +- Renamed Light2D point light to spot light +- 2D Renderer: The per Blend Style render texture scale setting was replaced by a global scale setting for all Blend Styles. +- Optimized 2D Renderer performance by using a tiny light texture for layer/blend style pairs for which no light is rendered. +- Reorgnized the settings in 2D Renderer Data Inspector. +- FallOff Lookup Texture is now part of 2D RenderData. +- Creating a Shadow Caster 2D will use try and use sprite and physics bounds as the default shape +- Deleting all points in a Shadow Caster will cause the shape to use the bounds. +- Improved Geometry for Smooth Falloff of 2D Shape Lights. +- Updated the tooltips for Light 2D Inspector. +- Removed the Custom blend Mode option from the Blend Styles. +- New default Blend Styles when a new 2D Renderer Data asset is created. +- Added a supported MSAA samples count check, so the actual supported MSAA samples count value can be assigned to RenderTexture descriptors. +- Bloom in Gamma color-space now more closely matches Linear color-space, this will mean project using Bloom and Gamma color-space may need to adjust Bloom Intensity to match previous look. +- Autodesk Interactive Shader Graph files and folders containing them were renamed. The new file paths do not have spaces. +- Moved `FinalPostProcessPass` to `AfterRenderingPostProcessing` event from `AfterRendering`. This allows user pass to execute before and after `FinalPostProcessPass` and `CapturePass` to capture everything. +- Changed shader keywords of main light shadow from toggling to enumerating. +- Always use "High" quality normals, which normalizes the normal in pixel shader. "Low" quality normals looked too much like a bug. +- Re-enabled implicit MSAA resolve to backbuffer on Metal MacOS. +- Optimized 2D performance by rendering straight to the backbuffer if possible +- Changed Post Process Data to bool. When it is no enabled all post processing is stripped from build, when it is enabled you can still override resources there. +- Converted XR automated tests to use MockHMD. +- Improved 2D Renderer performance on mobile GPUs when using MSAA +- Reduced the size of the fragment input struct of the Terrain and Forward lighting shaders. + +### Fixed +- Fixed an issue where additional lights would not render with WebGL 1 +- Fixed an issue where the 2D Renderer was incorrectly rendering transparency with normal maps on an empty background. +- Fixed an issue that that caused a null error when creating a Sprite Light. [case 1307125](https://issuetracker.unity3d.com/issues/urp-nullreferenceexception-thrown-on-creating-sprite-light-2d-object-in-the-hierarchy) +- Fixed an issue where Sprites on one Sorting Layer were fully lit even when there's no 2D light targeting that layer. +- Fixed an issue where null reference exception was thrown when creating a 2D Renderer Data asset while scripts are compiling. [case 1263040](https://issuetracker.unity3d.com/issues/urp-nullreferenceexception-error-is-thrown-on-creating-2d-renderer-asset) +- Fixed an issue where no preview would show for the lit sprite master node in shadergraph +- Fixed an issue where no shader was generated for unlit sprite shaders in shadergraph +- Fixed an issue where Sprite-Lit-Default shader's Normal Map property wasn't affected by Tiling or Offset. [case 1270850](https://issuetracker.unity3d.com/issues/sprite-lit-default-shaders-normal-map-and-mask-textures-are-not-affected-by-tiling-and-offset-values) +- Fixed an issue where normal-mapped Sprites could render differently depending on whether they're dynamically-batched. [case 1286186](https://issuetracker.unity3d.com/issues/urp-2d-2d-light-on-a-rotated-sprite-is-skewed-when-using-normal-map-and-sorting-layer-is-not-default) +- Removed the warning about mis-matched vertex streams when creating a default Particle System. [case 1285272](https://issuetracker.unity3d.com/issues/particles-urp-default-material-shows-warning-in-inspector) +- Fixed latest mockHMD renderviewport scale doesn't fill whole view after scaling. [case 1286161] (https://issuetracker.unity3d.com/issues/xr-urp-renderviewportscale-doesnt-fill-whole-view-after-scaling) +- Fixed camera renders black in XR when user sets invalid MSAA value. +- Fixed an issue causing additional lights to stop working when set as the sun source. [case 1278768](https://issuetracker.unity3d.com/issues/urp-every-light-type-is-rendered-as-directional-light-if-it-is-set-as-sun-source-of-the-environment) +- Fixed an issue causing passthrough camera to not render. [case 1283894](https://issuetracker.unity3d.com/product/unity/issues/guid/1283894/) +- Fixed an issue that caused a null reference when Lift Gamma Gain was being displayed in the Inspector and URP was upgraded to a newer version. [case 1283588](https://issuetracker.unity3d.com/issues/argumentnullexception-is-thrown-when-upgrading-urp-package-and-volume-with-lift-gamma-gain-is-focused-in-inspector) +- Fixed an issue where soft particles were not rendered when depth texture was disabled in the URP Asset. [case 1162556](https://issuetracker.unity3d.com/issues/lwrp-unlit-particles-shader-is-not-rendered-when-soft-particles-are-enabled-on-built-application) +- Fixed an issue where soft particles were rendered opaque on OpenGL. [case 1226288](https://issuetracker.unity3d.com/issues/urp-objects-that-are-using-soft-particles-are-rendered-opaque-when-opengl-is-used) +- Fixed an issue where the depth texture sample node used an incorrect texture in some frames. [case 1268079](https://issuetracker.unity3d.com/issues/urp-depth-texture-sample-node-does-not-use-correct-texture-in-some-frames) +- Fixed a compiler error in BakedLit shader when using Hybrid Renderer. +- Fixed an issue with upgrading material set to cutout didn't properly set alpha clipping. [case 1235516](https://issuetracker.unity3d.com/issues/urp-upgrade-material-utility-does-not-set-the-alpha-clipping-when-material-was-using-a-shader-with-rendering-mode-set-to-cutout) +- Fixed XR camera fov can be changed through camera inspector. +- Fixed an issue where Universal Render Pipeline with disabled antiAliasing was overwriting QualitySettings.asset on frequent cases. [case 1219159](https://issuetracker.unity3d.com/issues/urp-qualitysettings-dot-asset-file-gets-overwritten-with-the-same-content-when-the-editor-is-closed) +- Fixed a case where overlay camera with output texture caused base camera not to render to screen. [case 1283225](https://issuetracker.unity3d.com/issues/game-view-renders-a-black-view-when-having-an-overlay-camera-which-had-output-texture-assigned-in-the-camera-stack) +- Fixed an issue where the scene view camera ignored the pipeline assets HDR setting. [case 1284369](https://issuetracker.unity3d.com/issues/urp-scene-view-camera-ignores-pipeline-assets-hdr-settings-when-main-camera-uses-pipeline-settings) +- Fixed an issue where the Camera inspector was grabbing the URP asset in Graphics Settings rather than the currently active. +- Fixed an issue where the Light Explorer was grabbing the URP asset in Graphics Settings rather than the currently active. +- Fixed an issue causing materials to be upgraded multiple times. +- Fixed bloom inconsistencies between Gamma and Linear color-spaces. +- Fixed an issue in where all the entries in the Renderer List wasn't selectable and couldn't be deleted. +- Fixed Deferred renderer on some Android devices by forcing accurate GBuffer normals. [case 1288042] +- Fixed an issue where MSAA did not work in Editor Game View on Windows with Vulkan. +- Fixed issue where selecting and deselecting Forward Renderer asset would leak memory [case 1290628](https://issuetracker.unity3d.com/issues/urp-scriptablerendererfeatureeditor-memory-leak-while-interacting-with-forward-renderer-in-the-project-window) +- Fixed the default background color for previews to use the original color. +- Fixed an issue where the scene view would turn black when bloom was enabled. [case 1298790](https://issuetracker.unity3d.com/issues/urp-bloom-and-tonemapping-causes-the-screen-to-go-black-in-scene-mode) +- Fixed an issue where having "Opaque Texture" and MSAA enabled would cause the opaque texture to be rendered black on old Apple GPUs [case 1247423](https://issuetracker.unity3d.com/issues/urp-metal-opaque-objects-are-rendered-black-when-msaa-is-enabled) +- Fixed SAMPLE_TEXTURECUBE_ARRAY_LOD macro when using OpenGL ES. [case 1285132](https://issuetracker.unity3d.com/issues/urp-android-error-sample-texturecube-array-lod-is-not-supported-on-gles-3-dot-0-when-using-cubemap-array-shader-shaders) +- Fixed an issue such that it is now posible to enqueue render passes at runtime. +- Fixed SpeedTree LOD fade functionality. [case 1198135] + +## [10.2.0] - 2020-10-19 + +### Changed +- Changed RenderObjectsFeature UI to only expose valid events. Previously, when selecting events before BeforeRenderingPrepasses objects would not be drawn correctly as stereo and camera setup only happens before rendering opaques objects. +- Transparent Lit ShaderGraph using Additive blending will now properly fade with alpha [1270344] + +### Fixed +- Fixed the Unlit shader not being SRP Batcher compatible on OpenGLES/OpenGLCore. [case 1263720](https://issuetracker.unity3d.com/issues/urp-mobile-srp-batcher-is-not-visible-on-mobile-devices-in-frame-debugger) +- Fixed an issue with soft particles not rendering correctly for overlay cameras with post processing. [case 1241626](https://issuetracker.unity3d.com/issues/soft-particles-does-not-fade-out-near-the-opaque-surfaces-when-post-processing-is-enabled-on-a-stacked-camera) +- Fixed MSAA override on camera does not work in non-XR project if target eye is selected to both eye. + +## [10.1.0] - 2020-10-12 +- Added support for the Shadowmask Mixed Lighting Mode (Forward only), which supports up to four baked-shadow Lights. +- Added ComplexLit shader for advanced material features and deferred forward fallback. +- Added Clear Coat feature for ComplexLit shader and for shader graph. +- Added Parallax Mapping to the Lit shader (Lit.shader). +- Added the Detail Inputs setting group in the Lit shader (Lit.shader). +- Added Smooth shadow fading. +- Added SSAO support for deferred renderer. +- The pipeline now outputs a warning in the console when trying to access camera color or depth texture when those are not valid. Those textures are only available in the context of `ScriptableRenderPass`. +- Added a property to access the renderer from the `CameraData`. + +### Changed +- Shader functions SampleSH9, SampleSHPixel, SampleSHVertex are now gamma corrected in gamma space. As result LightProbes are gamma corrected too. +- The maximum number of visible lights when using OpenGL ES 3.x on Android now depends on the minimum OpenGL ES 3.x version as configured in PlayerSettings. +- The default value of the HDR property of a newly created Universal Render Pipeline Asset, is now set to true. + +### Fixed +- Fixed an issue where the CapturePass would not capture the post processing effects. +- Fixed an issue were the filter window could not be defocused using the mouse. [case 1242032](https://issuetracker.unity3d.com/issues/urp-volume-override-window-doesnt-disappear-when-clicked-on-the-other-windows-in-the-editor) +- Fixed camera backgrounds not matching between editor and build when background is set to 'Uninitialized'. [case 1224369](https://issuetracker.unity3d.com/issues/urp-uninitialized-camera-background-type-does-not-match-between-the-build-and-game-view) +- Fixed a case where main light hard shadows would not work if any other light is present with soft shadows.[case 1250829](https://issuetracker.unity3d.com/issues/main-light-shadows-are-ignored-in-favor-of-additional-lights-shadows) +- Fixed issue that caused color grading to not work correctly with camera stacking. [case 1263193](https://issuetracker.unity3d.com/product/unity/issues/guid/1263193/) +- Fixed an issue that caused an infinite asset database reimport when running Unity in command line with -testResults argument. +- Fixed ParticlesUnlit shader to use fog color instead of always black. [case 1264585] +- Fixed issue that caused some properties in the camera to not be bolded and highlighted when edited in prefab mode. [case 1230082](https://issuetracker.unity3d.com/issues/urp-camera-prefab-fields-render-type-renderer-background-type-are-not-bolded-and-highlighted-when-edited-in-prefab-mode) +- Fixed issue where blur would sometimes flicker [case 1224915](https://issuetracker.unity3d.com/issues/urp-bloom-effect-flickers-when-using-integrated-post-processing-feature-set) +- Fixed an issue in where the camera inspector didn't refresh properly when changing pipeline in graphic settings. [case 1222668](https://issuetracker.unity3d.com/issues/urp-camera-properties-not-refreshing-on-adding-or-removing-urp-pipeline-in-the-graphics-setting) +- Fixed depth of field to work with dynamic resolution. [case 1225467](https://issuetracker.unity3d.com/issues/dynamic-resolution-rendering-error-when-using-depth-of-field-in-urp) +- Fixed FXAA, SSAO, Motion Blur to work with dynamic resolution. +- Fixed an issue where Pixel lighting variants were stripped in builds if another URP asset had Additional Lights set to Per Vertex [case 1263514](https://issuetracker.unity3d.com/issues/urp-all-pixel-lighting-variants-are-stripped-in-build-if-at-least-one-urp-asset-has-additional-lights-set-to-per-vertex) +- Fixed an issue where transparent meshes were rendered opaque when using custom render passes [case 1262887](https://issuetracker.unity3d.com/issues/urp-transparent-meshes-are-rendered-as-opaques-when-using-lit-shader-with-custom-render-pass) +- Fixed regression from 8.x.x that increased launch times on Android with GLES3. [case 1269119](https://issuetracker.unity3d.com/issues/android-launch-times-increased-x4-from-urp-8-dot-1-0-to-urp-10-dot-0-0-preview-dot-26) +- Fixed an issue with a render texture failing assertion when chosing an invalid format. [case 1222676](https://issuetracker.unity3d.com/issues/the-error-occurs-when-a-render-texture-which-has-a-certain-color-format-is-applied-to-the-cameras-output-target) +- Fixed an issue that caused the unity_CameraToWorld matrix to have z flipped values. [case 1257518](https://issuetracker.unity3d.com/issues/parameter-unity-cameratoworld-dot-13-23-33-is-inverted-when-using-universal-rp-7-dot-4-1-and-newer) +- Fixed not using the local skybox on the camera game object when the Skybox Material property in the Lighting window was set to null. +- Fixed an issue where, if URP was not in use, you would sometimes get errors about 2D Lights when going through the menus. +- Fixed GC when using XR single-pass automated tests. +- Fixed an issue that caused a null reference when deleting camera component in a prefab. [case 1244430](https://issuetracker.unity3d.com/issues/urp-argumentnullexception-error-is-thrown-on-removing-camera-component-from-camera-prefab) +- Fixed resolution of intermediate textures when rendering to part of a render texture. [case 1261287](https://issuetracker.unity3d.com/product/unity/issues/guid/1261287/) +- Fixed indirect albedo not working with shadergraph shaders in some rare setups. [case 1274967](https://issuetracker.unity3d.com/issues/gameobjects-with-custom-mesh-are-not-reflecting-the-light-when-using-the-shader-graph-shaders) +- Fixed XR mirroView sRGB issue when color space is gamma. +- Fixed an issue where XR eye textures are recreated multiple times per frame due to per camera MSAA change. +- Fixed an issue wehre XR mirror view selector stuck. +- Fixed LightProbes to have gamma correct when using gamma color space. [case 1268911](https://issuetracker.unity3d.com/issues/urp-has-no-gamma-correction-for-lightprobes) +- Fixed GLES2 shader compilation. +- Fixed useless mip maps on temporary RTs/PostProcessing inherited from Main RT descriptor. +- Fixed issue with lens distortion breaking rendering when enabled and its intensity is 0. +- Fixed mixed lighting subtractive and shadowmask modes for deferred renderer. +- Fixed issue that caused motion blur to not work in XR. +- Fixed 2D renderer when using Linear rendering on Android directly to backbuffer. +- Fixed issue where multiple cameras would cause GC each frame. [case 1259717](https://issuetracker.unity3d.com/issues/urp-scriptablerendercontext-dot-getcamera-array-dot-resize-creates-garbage-every-frame-when-more-than-one-camera-is-active) +- Fixed Missing camera cannot be removed after scene is saved by removing the Missing camera label. [case 1252255](https://issuetracker.unity3d.com/issues/universal-rp-missing-camera-cannot-be-removed-from-camera-stack-after-scene-is-saved) +- Fixed MissingReferenceException when removing Missing camera from camera stack by removing Missing camera label. [case 1252263](https://issuetracker.unity3d.com/issues/universal-rp-missingreferenceexception-errors-when-removing-missing-camera-from-stack) +- Fixed slow down in the editor when editing properties in the UI for renderer features. [case 1279804](https://issuetracker.unity3d.com/issues/a-short-freeze-occurs-in-the-editor-when-expanding-or-collapsing-with-the-arrow-the-renderer-feature-in-the-forward-renderer) +- Fixed test 130_UnityMatrixIVP on OpenGL ES 3 +- Fixed MSAA on Metal MacOS and Editor. + +## [10.0.0] - 2020-06-10 +### Added +- Added the option to strip Terrain hole Shader variants. +- Added support for additional Directional Lights. The amount of additional Directional Lights is limited by the maximum Per-object Lights in the Render Pipeline Asset. +- Added Package Samples: 2 Camera Stacking, 2 Renderer Features +- Added default implementations of OnPreprocessMaterialDescription for FBX, Obj, Sketchup and 3DS file formats. +- Added Transparency Sort Mode and Transparency Sort Axis to 2DRendererData. +- Added support for a user defined default material to 2DRendererData. +- Added the option to toggle shadow receiving on transparent objects. +- Added XR multipass rendering. Multipass rendering is a requirement on many VR platforms and allows graceful fallback when single-pass rendering isn't available. +- Added support for Camera Stacking when using the Forward Renderer. This introduces the Camera `Render Type` property. A Base Camera can be initialized with either the Skybox or Solid Color, and can combine its output with that of one or more Overlay Cameras. An Overlay Camera is always initialized with the contents of the previous Camera that rendered in the Camera Stack. +- Added AssetPostprocessors and Shadergraphs to handle Arnold Standard Surface and 3DsMax Physical material import from FBX. +- Added `[MainTexture]` and `[MainColor]` shader property attributes to URP shader properties. These will link script material.mainTextureOffset and material.color to `_BaseMap` and `_BaseColor` shader properties. +- Added the option to specify the maximum number of visible lights. If you set a value, lights are sorted based on their distance from the Camera. +- Added the option to control the transparent layer separately in the Forward Renderer. +- Added the ability to set individual RendererFeatures to be active or not, use `ScriptableRendererFeature.SetActive(bool)` to set whether a Renderer Feature will execute, `ScriptableRendererFeature.isActive` can be used to check the current active state of the Renderer Feature. + additional steps to the 2D Renderer setup page for quality and platform settings. +- If Unity Editor Analytics are enabled, Universal collects anonymous data about usage of Universal. This helps the Universal team focus our efforts on the most common scenarios, and better understand the needs of our customers. +- Added a OnCameraSetup() function to the ScriptableRenderPass API, that gets called by the renderer before rendering each camera +- Added a OnCameraCleanup() function to the ScriptableRenderPass API, that gets called by the renderer after rendering each camera +- Added Default Material Type options to the 2D Renderer Data Asset property settings. +- Added additional steps to the 2D Renderer setup page for quality and platform settings. +- Added option to disable XR autotests on test settings. +- Shader Preprocessor strips gbuffer shader variants if DeferredRenderer is not in the list of renderers in any Scriptable Pipeline Assets. +- Added an option to enable/disable Adaptive Performance when the Adaptive Performance package is available in the project. +- Added support for 3DsMax's 2021 Simplified Physical Material from FBX files in the Model Importer. +- Added GI to SpeedTree +- Added support for DXT5nm-style normal maps on Android, iOS and tvOS +- Added stencil override support for deferred renderer. +- Added a warning message when a renderer is used with an unsupported graphics API, as the deferred renderer does not officially support GL-based platforms. +- Added option to skip a number of final bloom iterations. +- Added support for [Screen Space Ambient Occlusion](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.0/manual/post-processing-ssao.html) and a new shader variant _SCREEN_SPACE_OCCLUSION. +- Added support for Normal Texture being generated in a prepass. +- Added a ConfigureInput() function to ScriptableRenderPass, so it is possible for passes to ask that a Depth, Normal and/or Opaque textures to be generated by the forward renderer. +- Added a float2 normalizedScreenSpaceUV to the InputData Struct. +- Added new sections to documentation: [Writing custom shaders](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.0/manual/writing-custom-shaders-urp.html), and [Using the beginCameraRendering event](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.0/manual/using-begincamerarendering.html). +- Added support for GPU instanced mesh particles on supported platforms. +- Added API to check if a Camera or Light is compatible with Universal Render Pipeline. + +### Changed +- Moved the icon that indicates the type of a Light 2D from the Inspector header to the Light Type field. +- Eliminated some GC allocations from the 2D Renderer. +- Added SceneSelection pass for TerrainLit shader. +- Remove final blit pass to force alpha to 1.0 on mobile platforms. +- Deprecated the CinemachineUniversalPixelPerfect extension. Use the one from Cinemachine v2.4 instead. +- Replaced PlayerSettings.virtualRealitySupported with XRGraphics.tryEnable. +- Blend Style in the 2DRendererData are now automatically enabled/disabled. +- When using the 2D Renderer, Sprites will render with a faster rendering path when no lights are present. +- Particle shaders now receive shadows +- The Scene view now mirrors the Volume Layer Mask set on the Main Camera. +- Drawing order of SRPDefaultUnlit is now the same as the Built-in Render Pipline. +- Made MaterialDescriptionPreprocessors private. +- UniversalRenderPipelineAsset no longer supports presets. [Case 1197020](https://issuetracker.unity3d.com/issues/urp-reset-functionality-does-not-work-on-preset-of-universalrenderpipelineassets). +- The number of maximum visible lights is now determined by whether the platform is mobile or not. +- Renderer Feature list is now redesigned to fit more closely to the Volume Profile UI, this vastly improves UX and reliability of the Renderer Features List. +- Default color values for Lit and SimpleLit shaders changed to white due to issues with texture based workflows. +- You can now subclass ForwardRenderer to create a custom renderer based on it. +- URP is now computing tangent space per fragment. +- Optimized the 2D Renderer to skip rendering into certain internal buffers when not necessary. +- You can now subclass ForwardRenderer to create a custom renderer based on it. +- URP shaders that contain a priority slider now no longer have an offset of 50 by default. +- The virtual ScriptableRenderer.FrameCleanup() function has been marked obsolete and replaced by ScriptableRenderer.OnCameraCleanup() to better describe when the function gets invoked by the renderer. +- DepthOnlyPass, CopyDepthPass and CopyColorPass now use OnCameraSetup() instead of Configure() to set up their passes before executing as they only need to get their rendertextures once per camera instead of once per eye. +- Updated shaders to be compatible with Microsoft's DXC. +- Mesh GPU Instancing option is now hidden from the particles system renderer as this feature is not supported by URP. +- The 2D Renderer now supports camera stacking. +- 2D shaders now use half-precision floats whenever precise results are not necessary. +- Removed the ETC1_EXTERNAL_ALPHA variant from Shader Graph Sprite shaders. +- Eliminated some unnecessary clearing of render targets when using the 2D Renderer. +- The rendering of 2D lights is more effient as sorting layers affected by the same set of lights are now batched. +- Removed the 8 renderer limit from URP Asset. +- Merged the deferred renderer into the forward renderer. +- Changing the default value of Skip Iterations to 1 in Bloom effect editor +- Use SystemInfo to check if multiview is supported instead of being platform hardcoded +- Default attachment setup behaviour for ScriptableRenderPasses that execute before rendering opaques is now set use current the active render target setup. This improves performance in some situations. +- Combine XR occlusion meshes into one when using single-pass (multiview or instancing) to reduce draw calls and state changes. +- Shaders included in the URP package now use local Material keywords instead of global keywords. This increases the amount of available global user-defined Material keywords. + +### Fixed +- Fixed an issue that caused WebGL to render blank screen when Depth texture was enabled [case 1240228](https://issuetracker.unity3d.com/issues/webgl-urp-scene-is-rendered-black-in-webgl-build-when-depth-texture-is-enabled) +- Fixed NaNs in tonemap algorithms (neutral and ACES) on platforms defaulting to lower precision. +- Fixed a performance problem with ShaderPreprocessor with large amount of active shader variants in the project +- Fixed an issue where linear to sRGB conversion occurred twice on certain Android devices. +- Fixed an issue where there were 2 widgets showing the outer angle of a spot light. +- Fixed an issue where Unity rendered fullscreen quads with the pink error shader when you enabled the Stop NaN post-processing pass. +- Fixed an issue where Terrain hole Shader changes were missing. [Case 1179808](https://issuetracker.unity3d.com/issues/terrain-brush-tool-is-not-drawing-when-paint-holes-is-selected). +- Fixed an issue where the Shader Graph `SceneDepth` node didn't work with XR single-pass (double-wide) rendering. See [case 1123069](https://issuetracker.unity3d.com/issues/lwrp-vr-shadergraph-scenedepth-doesnt-work-in-single-pass-rendering). +- Fixed Unlit and BakedLit shader compilations in the meta pass. +- Fixed an issue where the Bokeh Depth of Field shader would fail to compile on PS4. +- Fixed an issue where the Scene lighting button didn't work when you used the 2D Renderer. +- Fixed a performance regression when you used the 2D Renderer. +- Fixed an issue where the Freeform 2D Light gizmo didn't correctly show the Falloff offset. +- Fixed an issue where the 2D Renderer rendered nothing when you used shadow-casting lights with incompatible Renderer2DData. +- Fixed an issue where errors were generated when the Physics2D module was not included in the project's manifest. +- Fixed an issue where Prefab previews were incorrectly lit when you used the 2D Renderer. +- Fixed an issue where the Light didn't update correctly when you deleted a Sprite that a Sprite 2D Light uses. +- Fixed an issue where 2D Lighting was broken for Perspective Cameras. +- Fixed an issue where resetting a Freeform 2D Light would throw null reference exceptions. [Case 1184536](https://issuetracker.unity3d.com/issues/lwrp-changing-light-type-to-freeform-after-clicking-on-reset-throws-multiple-arguementoutofrangeexception). +- Fixed an issue where Freeform 2D Lights were not culled correctly when there was a Falloff Offset. +- Fixed an issue where Tilemap palettes were invisible in the Tile Palette window when the 2D Renderer was in use. [Case 1162550](https://issuetracker.unity3d.com/issues/adding-tiles-in-the-tile-palette-makes-the-tiles-invisible). +- Fixed issue where black emission would cause unneccesary inspector UI repaints. [Case 1105661](https://issuetracker.unity3d.com/issues/lwrp-inspector-window-is-being-repainted-when-using-the-material-with-emission-enabled-and-set-to-black-00-0). +- Fixed user LUT sampling being done in Linear instead of sRGB. +- Fixed an issue when trying to get the Renderer via API on the first frame. [Case 1189196](https://issuetracker.unity3d.com/product/unity/issues/guid/1189196/). +- Fixed a material leak on domain reload. +- Fixed an issue where deleting an entry from the Renderer List and then undoing that change could cause a null reference. [Case 1191896](https://issuetracker.unity3d.com/issues/nullreferenceexception-when-attempting-to-remove-entry-from-renderer-features-list-after-it-has-been-removed-and-then-undone). +- Fixed an issue where the user would get an error if they removed the Additional Camera Data component. [Case 1189926](https://issuetracker.unity3d.com/issues/unable-to-remove-universal-slash-hd-additional-camera-data-component-serializedobject-target-destroyed-error-is-thrown). +- Fixed post-processing with XR single-pass rendering modes. +- Fixed an issue where Cinemachine v2.4 couldn't be used together with Universal RP due to a circular dependency between the two packages. +- Fixed an issue that caused shaders containing `HDRP` string in their path to be stripped from the build. +- Fixed an issue that caused only selected object to render in SceneView when Wireframe drawmode was selected. +- Fixed Renderer Features UI tooltips. [Case 1191901](https://issuetracker.unity3d.com/issues/forward-renderers-render-objects-layer-mask-tooltip-is-incorrect-and-contains-a-typo). +- Fixed multiple issues where Shader Graph shaders failed to build for XR in the Universal RP. +- Fixed an issue when using the 2D Renderer where some types of renderers would not be assigned the correct material. +- Fixed inconsistent lighting between the forward renderer and the deferred renderer, that was caused by a missing normalize operation on vertex normals on some speedtree shader variants. +- Fixed issue where XR Multiview failed to render when using URP Shader Graph Shaders +- Fixed lazy initialization with last version of ResourceReloader +- Fixed broken images in package documentation. +- Fixed an issue where viewport aspect ratio was wrong when using the Stretch Fill option of the Pixel Perfect Camera. [case 1188695](https://issuetracker.unity3d.com/issues/pixel-perfect-camera-component-does-not-maintain-the-aspect-ratio-when-the-stretch-fill-is-enabled) +- Fixed an issue where setting a Normal map on a newly created material would not update. [case 1197217](https://issuetracker.unity3d.com/product/unity/issues/guid/1197217/) +- Fixed an issue where post-processing was not applied for custom renderers set to run on the "After Rendering" event [case 1196219](https://issuetracker.unity3d.com/issues/urp-post-processing-is-not-applied-to-the-scene-when-render-ui-event-is-set-to-after-rendering) +- Fixed an issue that caused an extra blit when using custom renderers [case 1156741](https://issuetracker.unity3d.com/issues/lwrp-performance-decrease-when-using-a-scriptablerendererfeature) +- Fixed an issue with transparent objects not receiving shadows when using shadow cascades. [case 1116936](https://issuetracker.unity3d.com/issues/lwrp-cascaded-shadows-do-not-appear-on-alpha-blended-objects) +- Fixed issue where using a ForwardRendererData preset would cause a crash. [case 1201052](https://issuetracker.unity3d.com/product/unity/issues/guid/1201052/) +- Fixed an issue where particles had dark outlines when blended together [case 1199812](https://issuetracker.unity3d.com/issues/urp-soft-particles-create-dark-blending-artefacts-when-intersecting-with-scene-geometry) +- Fixed an issue with deleting shader passes in the custom renderer features list [case 1201664](https://issuetracker.unity3d.com/issues/urp-remove-button-is-not-activated-in-shader-passes-list-after-creating-objects-from-renderer-features-in-urpassets-renderer) +- Fixed camera inverse view-projection matrix in XR mode, depth-copy and color-copy passes. +- Fixed an issue with the null check when `UniversalRenderPipelineLightEditor.cs` tries to access `SceneView.lastActiveSceneView`. +- Fixed an issue where the 'Depth Texture' drop down was incorrectly disabled in the Camera Inspector. +- Fixed an issue that caused errors if you disabled the VR Module when building a project. +- Fixed an issue where the default TerrainLit Material was outdated, which caused the default Terrain to use per-vertex normals instead of per-pixel normals. +- Fixed shader errors and warnings in the default Universal RP Terrain Shader. [case 1185948](https://issuetracker.unity3d.com/issues/urp-terrain-slash-lit-base-pass-shader-does-not-compile) +- Fixed an issue where the URP Material Upgrader tried to upgrade standard Universal Shaders. [case 1144710](https://issuetracker.unity3d.com/issues/upgrading-to-lwrp-materials-is-trying-to-upgrade-lwrp-materials) +- Fixed an issue where some Materials threw errors when you upgraded them to Universal Shaders. [case 1200938](https://issuetracker.unity3d.com/issues/universal-some-materials-throw-errors-when-updated-to-universal-rp-through-update-materials-to-universal-rp) +- Fixed issue where normal maps on terrain appeared to have flipped X-components when compared to the same normal map on a mesh. [case 1181518](https://fogbugz.unity3d.com/f/cases/1181518/) +- Fixed an issue where the editor would sometimes crash when using additional lights [case 1176131](https://issuetracker.unity3d.com/issues/mac-crash-on-processshadowcasternodevisibilityandcullwithoutumbra-when-same-rp-asset-is-set-in-graphics-and-quality-settings) +- Fixed RemoveComponent on Camera contextual menu to not remove Camera while a component depend on it. +- Fixed an issue where right eye is not rendered to. [case 1170619](https://issuetracker.unity3d.com/issues/vr-lwrp-terrain-is-not-rendered-in-the-right-eye-of-an-hmd-when-using-single-pass-instanced-stereo-rendering-mode-with-lwrp) +- Fixed issue where TerrainDetailLit.shader fails to compile when XR is enabled. +- Fixed an issue that allowed height-based blending on Terrains with more than 4 materials, which is not supported. +- Fixed an issue where opaque objects were outputting incorrect alpha values [case 1168283](https://issuetracker.unity3d.com/issues/lwrp-alpha-clipping-material-makes-other-materials-look-like-alpha-clipping-when-gameobject-is-shown-in-render-texture) +- Fixed an issue where a depth texture was always created when post-processing was enabled, even if no effects made use of it. +- Fixed incorrect light attenuation on some platforms. +- Fixed an issue where the Volume System would not use the Cameras Transform when no `Volume Trigger` was set. +- Fixed an issue where post processing disappeared when using custom renderers and SMAA or no AA +- Fixed an issue where the 2D Renderer upgrader did not upgrade using the correct default material +- Fixed an issue with soft particles having dark blending when intersecting with scene geometry [case 1199812](https://issuetracker.unity3d.com/issues/urp-soft-particles-create-dark-blending-artefacts-when-intersecting-with-scene-geometry) +- Fixed an issue with additive particles blending incorrectly [case 1215713](https://issuetracker.unity3d.com/issues/universal-render-pipeline-additive-particles-not-using-vertex-alpha) +- Fixed an issue where camera preview window was missing in scene view. [case 1211971](https://issuetracker.unity3d.com/issues/scene-view-urp-camera-preview-window-is-missing-in-the-scene-view) +- Fixed an issue with shadow cascade values were not readable in the render pipeline asset [case 1219003](https://issuetracker.unity3d.com/issues/urp-cascade-values-truncated-on-selecting-two-or-four-cascades-in-shadows-under-universalrenderpipelineasset) +- Fixed an issue where MSAA isn't applied until eye textures are relocated by changing their resolution. [case 1197958](https://issuetracker.unity3d.com/issues/oculus-quest-oculus-go-urp-msaa-isnt-applied-until-eye-textures-are-relocated-by-changing-their-resolution) +- Fixed an issue where camera stacking didn't work properly inside prefab mode. [case 1220509](https://issuetracker.unity3d.com/issues/urp-cannot-assign-overlay-cameras-to-a-camera-stack-while-in-prefab-mode) +- Fixed the definition of `mad()` in SMAA shader for OpenGL. +- Fixed an issue where partical shaders failed to handle Single-Pass Stereo VR rendering with Double-Wide Textures. [case 1201208](https://issuetracker.unity3d.com/issues/urp-vr-each-eye-uses-the-cameraopaquetexture-of-both-eyes-for-rendering-when-using-single-pass-rendering-mode) +- Fixed an issue that caused assets to be reimported if player prefs were cleared. [case 1192259](https://issuetracker.unity3d.com/issues/lwrp-clearing-playerprefs-through-a-script-or-editor-causes-delay-and-console-errors-to-appear-when-entering-the-play-mode) +- Fixed missing Custom Render Features after Library deletion. [case 1196338](https://issuetracker.unity3d.com/product/unity/issues/guid/1196338/) +- Fixed not being able to remove a Renderer Feature due to tricky UI selection rects. [case 1208113](https://issuetracker.unity3d.com/product/unity/issues/guid/1208113/) +- Fixed an issue where the Camera Override on the Render Object Feature would not work with many Render Features in a row. [case 1205185](https://issuetracker.unity3d.com/product/unity/issues/guid/1205185/) +- Fixed UI clipping issue in Forward Renderer inspector. [case 1211954](https://issuetracker.unity3d.com/product/unity/issues/guid/1211954/) +- Fixed a Null ref when trying to remove a missing Renderer Feature from the Forward Renderer. [case 1196651](https://issuetracker.unity3d.com/product/unity/issues/guid/1196651/) +- Fixed data serialization issue when adding a Renderer Feature to teh Forward Renderer. [case 1214779](https://issuetracker.unity3d.com/product/unity/issues/guid/1214779/) +- Fixed issue with AssetPostprocessors dependencies causing models to be imported twice when upgrading the package version. +- Fixed an issue where NullReferenceException might be thrown when creating 2D Lights. [case 1219374](https://issuetracker.unity3d.com/issues/urp-nullreferenceexception-threw-on-adding-the-light-2d-experimental-component-when-2d-render-data-not-assigned) +- Fixed an issue with a blurry settings icon. [case 1201895](https://issuetracker.unity3d.com/issues/urp-setting-icon-blurred-in-universalrendererpipelineasset) +- Fixed issue that caused the QualitySettings anti-aliasing changing without user interaction. [case 1195272](https://issuetracker.unity3d.com/issues/lwrp-the-anti-alias-quality-settings-value-is-changing-without-user-interaction) +- Fixed an issue where Shader Graph shaders generate undeclared identifier 'GetWorldSpaceNormalizeViewDir' error. +- Fixed an issue where rendering into RenderTexture with Single Pass Instanced renders both eyes overlapping. +- Fixed an issue where Renderscale setting has no effect when using XRSDK. +- Fixed an issue where renderScale != 1 or Display.main.requiresBlitToBackbuffer forced an unnecessary blit on XR. +- Fixed an issue that causes double sRGB correction on Quest. [case 1209292](https://issuetracker.unity3d.com/product/unity/issues/guid/1209292) +- Fixed an issue where terrain DepthOnly pass does not work for XR. +- Fixed an issue that caused depth texture to be flipped when sampling from shaders [case 1225362](https://issuetracker.unity3d.com/issues/game-object-is-rendered-incorrectly-in-the-game-view-when-sampling-depth-texture) +- Fixed an issue with URP switching such that every avaiable URP makes a total set of supported features such that all URPs are taken into consideration. [case 1157420](https://issuetracker.unity3d.com/issues/lwrp-srp-switching-doesnt-work-even-with-manually-adding-shadervariants-per-scene) +- Fixed an issue where XR multipass repeatedly throws error messages "Multi pass stereo mode doesn't support Camera Stacking". +- Fixed an issue with shadows not appearing on terrains when no cascades were selected [case 1226530](https://issuetracker.unity3d.com/issues/urp-no-shadows-on-terrain-when-cascades-is-set-to-no-cascades-in-render-pipeline-asset-settings) +- Fixed a shader issue that caused the Color in Sprite Shape to work improperly. +- Fixed an issue with URP switching such that every available URP makes a total set of supported features such that all URPs are taken into consideration. [case 1157420](https://issuetracker.unity3d.com/issues/lwrp-srp-switching-doesnt-work-even-with-manually-adding-shadervariants-per-scene) +- Metallic slider on the Lit shader is now linear meaning correct values are used for PBR. +- Fixed an issue where Post-Processing caused nothing to render on GLES2. +- Fixed an issue that causes viewport to not work correctly when rendering to textures. [case 1225103](https://issuetracker.unity3d.com/issues/urp-the-viewport-rect-isnt-correctly-applied-when-the-camera-is-outputting-into-a-rendertexture) +- Fixed an issue that caused incorrect sampling of HDR reflection probe textures. +- Fixed UI text of RenderObjects feature to display LightMode tag instead of Shader Pass Name. [case 1201696](https://issuetracker.unity3d.com/issues/render-feature-slash-pass-ui-has-a-field-for-shader-pass-name-when-it-actually-expects-shader-pass-lightmode) +- Fixed an issue when Linear -> sRGB conversion would not happen on some Android devices. [case 1226208](https://issuetracker.unity3d.com/issues/no-srgb-conversion-on-some-android-devices-when-using-the-universal-render-pipeline) +- Fixed issue where using DOF at the same time as Dynamic Scaling, the depth buffer was smapled with incorrect UVs. [case 1225467](https://issuetracker.unity3d.com/product/unity/issues/guid/1225467/) +- Fixed an issue where an exception would be thrown when resetting the ShadowCaster2D component. [case 1225339](https://issuetracker.unity3d.com/issues/urp-unassignedreferenceexception-thrown-on-resetting-the-shadow-caster-2d-component) +- Fixe an issue where using a Subtractive Blend Style for your 2D Lights might cause artifacts in certain post-processing effects. [case 1215584](https://issuetracker.unity3d.com/issues/urp-incorrect-colors-in-scene-when-using-subtractive-and-multiply-blend-mode-in-gamma-color-space) +- Fixed an issue where Cinemachine Pixel Perfect Extension didn't work when CinemachineBrain Update Method is anything other than Late Update. +- Fixed an issue where Sprite Shader Graph shaders weren't double-sided by default. +- Fixed an issue where particles using Sprite Shader Graph shaders were invisible. +- Fixed an issue where Scene objects might be incorrectly affected by 2D Lights from a previous Sorting Layer. +- Fixed an issue where errors would appear in the Console when entering Play Mode with a 2D Light selected in the Hierarchy. [Case 1226918](https://issuetracker.unity3d.com/issues/errors-appear-in-the-console-when-global-2d-light-is-selected-in-hierarchy) +- Fixed an issue that caused Android GLES to render blank screen when Depth texture was enabled without Opaque texture [case 1219325](https://issuetracker.unity3d.com/issues/scene-is-not-rendered-on-android-8-and-9-when-depth-texture-is-enabled-in-urp-asset) +- Fixed an issue that caused transparent objects to always render over top of world space UI. [case 1219877](https://issuetracker.unity3d.com/product/unity/issues/guid/1219877/) +- Fixed issue causing sorting fudge to not work between shadergraph and urp particle shaders. [case 1222762](https://issuetracker.unity3d.com/product/unity/issues/guid/1222762/) +- Fixed shader compilation errors when using multiple lights in DX10 level GPU. [case 1222302](https://issuetracker.unity3d.com/issues/urp-no-materials-apart-from-ui-are-rendered-when-using-direct3d11-graphics-api-on-a-dx10-gpu) +- Fixed an issue with shadows not being correctly calculated in some shaders. +- Fixed invalid implementation of one function in LWRP -> URP backward compatibility support. +- Fixed issue where maximum number of visible lights in C# code did not match maximum number in shader code on some platforms. +- Fixed OpenGL ES 3.0 support for URP ShaderGraph. [case 1230890](https://issuetracker.unity3d.com/issues/urptemplate-gles3-android-custom-shader-fails-to-compile-on-adreno-306-gpu) +- Fixed an issue where multi edit camera properties didn't work. [case 1230080](https://issuetracker.unity3d.com/issues/urp-certain-settings-are-not-applied-to-all-cameras-when-multi-editing-in-the-inspector) +- Fixed an issue where the emission value in particle shaders would not update in the editor without entering the Play mode. +- Fixed issues with performance when importing fbx files. +- Fixed issues with NullReferenceException happening with URP shaders. +- Fixed an issue that caused memory allocations when sorting cameras. [case 1226448](https://issuetracker.unity3d.com/issues/2d-renderer-using-more-than-one-camera-that-renders-out-to-a-render-texture-creates-gc-alloc-every-frame) +- Fixed an issue where grid lines were drawn on top of opaque objects in the preview window. [Case 1240723](https://issuetracker.unity3d.com/issues/urp-grid-is-rendered-in-front-of-the-model-in-the-inspector-animation-preview-window-when-depth-or-opaque-texture-is-enabled). +- Fixed an issue where objects in the preview window were affected by layer mask settings in the default renderer. [Case 1204376](https://issuetracker.unity3d.com/issues/urp-prefab-preview-is-blank-when-a-custom-forward-renderer-data-and-default-layer-mask-is-mixed-are-used). +- Fixed an issue with reflections when using an orthographic camera [case 1209255](https://issuetracker.unity3d.com/issues/urp-weird-reflections-when-using-lit-material-and-a-camera-with-orthographic-projection) +- Fixed issue that caused unity_AmbientSky, unity_AmbientEquator and unity_AmbientGround variables to be unintialized. +- Fixed issue that caused `SHADERGRAPH_AMBIENT_SKY`, `SHADERGRAPH_AMBIENT_EQUATOR` and `SHADERGRAPH_AMBIENT_GROUND` variables to be uninitialized. +- Fixed SceneView Draw Modes not being properly updated after opening new scene view panels or changing the editor layout. +- Fixed GLES shaders compilation failing on Windows platform (not a mobile platform) due to uniform count limit. +- Fixed an issue that caused the inverse view and projection matrix to output wrong values in some platforms. [case 1243990](https://issuetracker.unity3d.com/issues/urp-8-dot-1-breaks-unity-matrix-i-vp) +- Fixed an issue where the Render Scale setting of the pipeline asset didn't properly change the resolution when using the 2D Renderer. [case 1241537](https://issuetracker.unity3d.com/issues/render-scale-is-not-applied-to-the-rendered-image-when-2d-renderer-is-used-and-hdr-option-is-disabled) +- Fixed an issue where 2D lights didn't respect the Camera's Culling Mask. [case 1239136](https://issuetracker.unity3d.com/issues/urp-2d-2d-lights-are-ignored-by-camera-culling-mask) +- Fixed broken documentation links for some 2D related components. +- Fixed an issue where Sprite shaders generated by Shader Graph weren't double-sided. [case 1261232](https://issuetracker.unity3d.com/product/unity/issues/guid/1261232/) +- Fixed an issue where the package would fail to compile if the Animation module was disabled. [case 1227068](https://issuetracker.unity3d.com/product/unity/issues/guid/1227068/) +- Fixed an issue where Stencil settings wasn't serialized properly in sub object [case 1241218](https://issuetracker.unity3d.com/issues/stencil-overrides-in-urp-7-dot-3-1-render-objects-does-not-save-or-apply) +- Fixed an issue with not being able to remove Light Mode Tags [case 1240895](https://issuetracker.unity3d.com/issues/urp-unable-to-remove-added-lightmode-tags-of-filters-property-in-render-object) +- Fixed an issue where preset button could still be used, when it is not supposed to. [case 1246261](https://issuetracker.unity3d.com/issues/urp-reset-functionality-does-not-work-for-renderobject-preset-asset) +- Fixed an issue where Model Importer Materials used the Standard Shader from the Built-in Render Pipeline instead of URP Lit shader when the import happened at Editor startup. +- Fixed an issue where only unique names of cameras could be added to the camera stack. +- Fixed issue that caused shaders to fail to compile in OpenGL 4.1 or below. +- Fixed an issue where camera stacking with MSAA on OpenGL resulted in a black screen. [case 1250602](https://issuetracker.unity3d.com/issues/urp-camera-stacking-results-in-black-screen-when-msaa-and-opengl-graphics-api-are-used) +- Optimized shader compilation times by compiling different variant sets for vertex and fragment shaders. +- Fixed shadows for additional lights by limiting MAX_VISIBLE_LIGHTS to 16 for OpenGL ES 2.0 and 3.0 on mobile platforms. [case 1244391](https://issuetracker.unity3d.com/issues/android-urp-spotlight-shadows-are-not-being-rendered-on-adreno-330-and-320-when-built) +- Fixed Lit/SimpleLit/ParticlesLit/ParticlesSimpleLit/ParticlesUnlit shaders emission color not to be converted from gamma to linear color space. [case 1249615] +- Fixed missing unity_MatrixInvP for shader code and shaderGraph. +- Fixed XR support for deferred renderer. +- Fixing RenderObject to reflect name changes done at CustomForwardRenderer asset in project view. [case 1246256](https://issuetracker.unity3d.com/issues/urp-renderobject-name-does-not-reflect-inside-customforwardrendererdata-asset-on-renaming-in-the-inspector) +- Fixing camera overlay stacking adding to respect unity general reference restrictions. [case 1240788](https://issuetracker.unity3d.com/issues/urp-overlay-camera-is-missing-in-stack-list-of-the-base-camera-prefab) +- Fixed profiler marker errors. [case 1240963](https://issuetracker.unity3d.com/issues/urp-errors-are-thrown-in-a-console-when-using-profiler-to-profile-editor) +- Fixed issue that caused the pipeline to not create _CameraColorTexture if a custom render pass is injected. [case 1232761](https://issuetracker.unity3d.com/issues/urp-the-intermediate-color-texture-is-no-longer-created-when-there-is-at-least-one-renderer-feature) +- Fixed target eye UI for XR rendering is missing from camera inspector. [case 1261612](https://issuetracker.unity3d.com/issues/xr-cameras-target-eye-property-is-missing-when-inspector-is-in-normal-mode) +- Fixed an issue where terrain and speedtree materials would not get upgraded by upgrade project materials. [case 1204189](https://fogbugz.unity3d.com/f/cases/1204189/) +- Fixed an issue that caused renderer feature to not render correctly if the pass was injected before rendering opaques and didn't implement `Configure` method. [case 1259750](https://issuetracker.unity3d.com/issues/urp-not-rendering-with-a-renderer-feature-before-rendering-shadows) +- Fixed an issue where postFX's temp texture is not released properly. +- Fixed an issue where ArgumentOutOfRangeException errors were thrown after removing Render feature [case 1268147](https://issuetracker.unity3d.com/issues/urp-argumentoutofrangeexception-errors-are-thrown-on-undoing-after-removing-render-feature) +- Fixed an issue where depth and depth/normal of grass isn't rendered to depth texture. +- Fixed an issue that impacted MSAA performance on iOS/Metal [case 1219054](https://issuetracker.unity3d.com/issues/urp-ios-msaa-has-a-bigger-negative-impact-on-performance-when-using-urp-compared-to-built-in-rp) +- Fixed an issue that caused a warning to be thrown about temporary render texture not found when user calls ConfigureTarget(0). [case 1220871](https://issuetracker.unity3d.com/issues/urp-scriptable-render-passes-which-dont-require-a-bound-render-target-triggers-render-target-warning) +- Fixed performance issues in the C# shader stripper. + +## [7.1.1] - 2019-09-05 +### Upgrade Guide +- The render pipeline now handles custom renderers differently. You must now set up renderers for the Camera on the Render Pipeline Asset. +- Render Pipeline Assets upgrades automatically and either creates a default forward renderer in your project or links the existing custom one that you've assigned. +- If you have custom renderers assigned to Cameras, you must now add them to the current Render Pipeline Asset. Then you can select which renderer to use on the Camera. + +### Added +- Added shader function `GetMainLightShadowParams`. This returns a half4 for the main light that packs shadow strength in x component and shadow soft property in y component. +- Added shader function `GetAdditionalLightShadowParams`. This returns a half4 for an additional light that packs shadow strength in x component and shadow soft property in y component. +- Added a `Debug Level` option to the Render Pipeline Asset. With this, you can control the amount of debug information generated by the render pipeline. +- Added ability to set the `ScriptableRenderer` that the Camera renders with via C# using `UniversalAdditionalCameraData.SetRenderer(int index)`. This maps to the **Renderer List** on the Render Pipeline Asset. +- Added shadow support for the 2D Renderer. +- Added ShadowCaster2D, and CompositeShadowCaster2D components. +- Added shadow intensity and shadow volume intensity properties to Light2D. +- Added new Gizmos for Lights. +- Added CinemachineUniversalPixelPerfect, a Cinemachine Virtual Camera Extension that solves some compatibility issues between Cinemachine and Pixel Perfect Camera. +- Added an option that disables the depth/stencil buffer for the 2D Renderer. +- Added manipulation handles for the inner cone angle for spot lights. +- Added documentation for the built-in post-processing solution and Volumes framework (and removed incorrect mention of the PPv2 package). + +### Changed +- Increased visible lights limit for the forward renderer. It now supports 256 visible lights except in mobile platforms. Mobile platforms support 32 visible lights. +- Increased per-object lights limit for the forward renderer. It now supports 8 per-object lights in all platforms except GLES2. GLES2 supports 4 per-object lights. +- The Sprite-Lit-Default shader and the Sprite Lit Shader Graph shaders now use the vertex tangents for tangent space calculations. +- Temporary render textures for cameras rendering to render textures now use the same format and multisampling configuration as camera's target texture. +- All platforms now use R11G11B10_UFloat format for HDR render textures if supported. +- There is now a list of `ScriptableRendererData` on the Render Pipeline Asset as opposed to a renderer type. These are available to all Cameras and are included in builds. +- The renderer override on the Camera is now an enum that maps to the list of `ScriptableRendererData` on the Render Pipeline Asset. +- Pixel Perfect Camera now allows rendering to a render texture. +- Light2D GameObjects that you've created now have a default position with z equal to 0. +- Documentation: Changed the "Getting Started" section into "Install and Configure". Re-arranged the Table of Content. + +### Fixed +- Fixed LightProbe occlusion contribution. [case 1146667](https://issuetracker.unity3d.com/product/unity/issues/guid/1146667/) +- Fixed an issue that caused a log message to be printed in the console when creating a new Material. [case 1173160](https://issuetracker.unity3d.com/product/unity/issues/guid/1173160/) +- Fixed an issue where OnRenderObjectCallback was never invoked. [case 1122420](https://issuetracker.unity3d.com/issues/lwrp-gl-dot-lines-and-debug-dot-drawline-dont-render-when-scriptable-render-pipeline-settings-is-set-to-lwrp) +- Fixed an issue where Sprite Masks didn't function properly when using the 2D Renderer. [case 1163474](https://issuetracker.unity3d.com/issues/lwrp-sprite-renderer-ignores-sprite-mask-when-lightweight-render-pipeline-asset-data-is-set-to-2d-renderer-experimental) +- Fixed memory leaks when using the Frame Debugger with the 2D Renderer. +- Fixed an issue where materials using `_Time` did not animate in the scene. [1175396](https://issuetracker.unity3d.com/product/unity/issues/guid/1175396/) +- Fixed an issue where the Particle Lit shader had artifacts when both soft particles and HDR were enabled. [1136285](https://issuetracker.unity3d.com/product/unity/issues/guid/1136285/) +- Fixed an issue where the Area Lights were set to Realtime, which caused them to not bake. [1159838](https://issuetracker.unity3d.com/issues/lwrp-template-baked-area-lights-do-not-work-if-project-is-created-with-lightweight-rp-template) +- Fixed an issue where the Disc Light did not generate any light. [1175097](https://issuetracker.unity3d.com/issues/using-lwrp-area-light-does-not-generate-light-when-its-shape-is-set-to-disc) +- Fixed an issue where the alpha was killed when an opaque texture was requested on an offscreen camera with HDR enabled [case 1163320](https://issuetracker.unity3d.com/issues/lwrp-mobile-secondary-camera-background-alpha-value-is-lost-when-hdr-and-opaque-texture-are-enabled-in-lwrp-asset). +- Fixed an issue that caused Orthographic camera with far plane set to 0 to span Unity console with errors. [case 1172269](https://issuetracker.unity3d.com/issues/orthographic-camera-with-far-plane-set-to-0-results-in-assertions) +- Fixed an issue causing heap allocation in `RenderPipelineManager.DoRenderLoop` [case 1156241](https://issuetracker.unity3d.com/issues/lwrp-playerloop-renderpipelinemanager-dot-dorenderloop-internal-gc-dot-alloc-allocates-around-2-dot-6kb-for-every-camera-in-the-scene) +- Fixed an issue that caused shadow artifacts when using large spot angle values [case 1136165](https://issuetracker.unity3d.com/issues/lwrp-adjusting-spot-angle-on-a-spotlight-produces-shadowmap-artifacts) +- Fixed an issue that caused self-shadowing artifacts when adjusting shadow near-plane on spot lights. +- Fixed an issue that caused specular highlights to disappear when the smoothness value was set to 1.0. [case 1161827](https://issuetracker.unity3d.com/issues/lwrp-hdrp-lit-shader-max-smoothness-value-is-incosistent-between-pipelines) +- Fixed an issue in the Material upgrader that caused transparent Materials to not upgrade correctly to Universal RP. [case 1170419](https://issuetracker.unity3d.com/issues/shader-conversion-upgrading-project-materials-causes-standard-transparent-materials-to-flicker-when-moving-the-camera). +- Fixed an issue causing shadows to be incorrectly rendered when a light was close to the shadow caster. +- Fixed post-processing for the 2D Renderer. +- Fixed an issue in Light2D that caused a black line to appear for a 360 degree spotlight. +- Fixed a post-processing rendering issue with non-fullscreen viewport. [case 1177660](https://issuetracker.unity3d.com/issues/urp-render-scale-slider-value-modifies-viewport-coordinates-of-the-screen-instead-of-the-resolution) +- Fixed an issue where **Undo** would not undo the creation of Additional Camera Data. [case 1158861](https://issuetracker.unity3d.com/issues/lwrp-additional-camera-data-script-component-appears-on-camera-after-manually-re-picking-use-pipeline-settings) +- Fixed an issue where selecting the same drop-down menu item twice would trigger a change event. [case 1158861](https://issuetracker.unity3d.com/issues/lwrp-additional-camera-data-script-component-appears-on-camera-after-manually-re-picking-use-pipeline-settings) +- Fixed an issue where selecting certain objects that use instancing materials would throw console warnings. [case 1127324](https://issuetracker.unity3d.com/issues/console-warning-is-being-spammed-when-having-lwrp-enabled-and-shader-with-gpu-instancing-present-in-the-scene) +- Fixed a GUID conflict with LWRP. [case 1179895](https://issuetracker.unity3d.com/product/unity/issues/guid/1179895/) +- Fixed an issue where the Terrain shader generated NaNs. +- Fixed an issue that caused the `Opaque Color` pass to never render at half or quarter resolution. +- Fixed and issue where stencil state on a `ForwardRendererData` was reset each time rendering happened. + +## [7.0.1] - 2019-07-25 +### Changed +- Platform checks now provide more helpful feedback about supported features in the Inspectors. + +### Fixed +- Fixed specular lighting related artifacts on Mobile [case 1143049](https://issuetracker.unity3d.com/issues/ios-lwrp-rounded-cubes-has-graphical-artifacts-when-setting-pbr-shaders-smoothness-about-to-0-dot-65-in-shadergraph) and [case 1164822](https://issuetracker.unity3d.com/issues/lwrp-specular-highlight-becomes-hard-edged-when-increasing-the-size-of-an-object). +- Post-processing is no longer enabled in the previews. +- Unity no longer force-enables post-processing on a camera by default. +- Fixed an issue that caused the Scene to render darker in GLES3 and linear color space. [case 1169789](https://issuetracker.unity3d.com/issues/lwrp-android-scene-is-rendered-darker-in-build-when-graphics-api-set-to-gles3-and-color-space-set-to-linear) + +## [7.0.0] - 2019-07-17 +### Universal Render Pipeline +- LWRP has been renamed to the "Universal Render Pipeline" (UniversalRP). +- UniversalRP is the same as LWRP in terms of features and scope. +- Classes have moved to the Universal namespace (from LWRP). + +### Upgrade Guide +- Upgrading to URP is designed to be almost seamless from the user side. +- LWRP package still exists, this forwards includes and classes to the UniversalRP Package. +- Please see the more involved upgrade guide (https://docs.google.com/document/d/1Xd5bZa8pYZRHri-EnNkyhwrWEzSa15vtnpcg--xUCIs/). + +### Added +- Initial Stadia platform support. +- Added a menu option to create a new `ScriptableRendererFeature` script. To do so in the Editor, click on Asset > Create > Rendering > Lightweight Render Pipeline > Renderer Feature. +- Added documentation for SpeedTree Shaders in LWRP. +- Added extended features to LWRP Terrain Shader, so terrain assets can be forward-compatible with HDRP. +- Enabled per-layer advanced or legacy-mode blending in LWRP Terrain Shader. +- Added the documentation page "Rendering in LWRP", which describes the forward rendering camera loop. +- Added documentation overview for how Post Processing Version 2 works in LWRP. +- Added documentation notes and FAQ entry on the 2D Renderer affecting the LWRP Asset. + +### Changed +- Replaced beginCameraRendering callbacks by non obsolete implementation in Light2D +- Updated `ScriptableRendererFeature` and `ScriptableRenderPass` API docs. +- Changed shader type Real to translate to FP16 precision on some platforms. + +### Fixed +- Fixed a case where built-in Shader time values could be out of sync with actual time. [case 1142495](https://fogbugz.unity3d.com/f/cases/1142495/) +- Fixed an issue that caused forward renderer resources to not load properly when you upgraded LWRP from an older version to 7.0.0. [case 1154925](https://issuetracker.unity3d.com/issues/lwrp-upgrading-lwrp-package-to-7-dot-0-0-breaks-forwardrenderdata-asset-in-resource-files) +- Fixed GC spikes caused by LWRP allocating heap memory every frame. +- Fixed distortion effect on particle unlit shader. +- Fixed NullReference exception caused when trying to add a ScriptableRendererFeature. +- Fixed issue with certain LWRP shaders not showing when using forward/2D renderer. +- Fixed the shadow resolve pass and the final pass, so they're not consuming unnecessary bandwidth. [case 1152439](https://issuetracker.unity3d.com/issues/lwrp-mobile-increased-memory-usage-and-extra-rendering-steps) +- Added missing page for 2D Lights in LWRP. +- Tilemap tiles no longer appear black when you use the 2D renderer. +- Sprites in the preview window are no longer lit by 2D Scene lighting. +- Fixed warnings for unsupported shadow map formats for GLES2 API. +- Disabled shadows for devices that do not support shadow maps or depth textures. +- Fixed support for LWRP per-pixel terrain. [case 1110520](https://fogbugz.unity3d.com/f/cases/1110520) +- Fixed some basic UI/usability issues with LWRP terrain Materials (use of warnings and modal value changes). +- Fixed an issue where using LWRP and Sprite Shape together would produce meta file conflicts. +- Fixed specular calculation fp16 overflow on some platforms +- Fixed shader compilation errors for Android XR projects. +- Updated the pipeline Asset UI to cap the render scale at 2x so that it matches the render pipeline implementation limit. + +## [6.7.0] - 2019-05-16 +### Added +- Added SpeedTree Shaders. +- Added two Shader Graph master nodes: Lit Sprite and Unlit Sprite. They only work with the 2D renderer. +- Added documentation for the 2D renderer. + +### Changed +- The 2D renderer and Light2D component received a number of improvements and are now ready to try as experimental features. +- Updated the [Feature Comparison Table](lwrp-builtin-feature-comparison.md) to reflect the current state of LWRP features. + +### Fixed +- When in playmode, the error 'Non matching Profiler.EndSample' no longer appears. [case 1140750](https://fogbugz.unity3d.com/f/cases/1140750/) +- LWRP Particle Shaders now correctly render in stereo rendering modes. [case 1106699](https://fogbugz.unity3d.com/f/cases/1106699/) +- Shaders with 'debug' in the name are no longer stripped automatically. [case 1112983](https://fogbugz.unity3d.com/f/cases/1112983/) +- Fixed tiling issue with selection outline and baked cutout shadows. +- in the Shadergraph Unlit Master node, Premultiply no longer acts the same as Alpha. [case 1114708](https://fogbugz.unity3d.com/f/cases/1114708/) +- Fixed an issue where Lightprobe data was missing if it was needed per-pixel and GPU instancing was enabled. +- The Soft ScreenSpaceShadows Shader variant no longer gets stripped form builds. [case 1138236](https://fogbugz.unity3d.com/f/cases/1138236/) +- Fixed a typo in the Particle Unlit Shader, so Soft Particles now work correctly. +- Fixed emissive Materials not being baked for some meshes. [case 1145297](https://issuetracker.unity3d.com/issues/lwrp-emissive-materials-are-not-baked) +- Camera matrices are now correctly set up when you call rendering functions in EndCameraRendering. [case 1146586](https://issuetracker.unity3d.com/issues/lwrp-drawmeshnow-returns-wrong-positions-slash-scales-when-called-from-endcamerarendering-hook) +- Fixed GI not baking correctly while in gamma color space. +- Fixed a NullReference exception when adding a renderer feature that is contained in a global namespace. [case 1147068](https://issuetracker.unity3d.com/issues/scriptablerenderpipeline-inspector-ui-crashes-when-a-scriptablerenderfeature-is-not-in-a-namespace) +- Shaders are now set up for VR stereo instancing on Vulkan. [case 1142952](https://fogbugz.unity3d.com/f/cases/1142952/). +- VR stereo matrices and vertex inputs are now set up on Vulkan. [case 1142952](https://fogbugz.unity3d.com/f/cases/1142952/). +- Fixed the Material Upgrader so it's now run upon updating the LWRP package. [1148764](https://issuetracker.unity3d.com/product/unity/issues/guid/1148764/) +- Fixed a NullReference exception when you create a new Lightweight Render Pipeline Asset. [case 1153388](https://issuetracker.unity3d.com/product/unity/issues/guid/1153388/) + +## [6.6.0] - 2019-04-01 +### Added +- Added support for Baked Indirect mixed lighting. +- You can now use Light Probes for occlusion. This means that baked lights can now occlude dynamic objects. +- Added RenderObjects. You can add RenderObjects to a Renderer to perform custom rendering. +- (WIP) Added an experimental 2D renderer that implements a 2D lighting system. +- (WIP) Added a Light2D component that works with the 2D renderer to add lighting effects to 2D sprites. + +### Fixed +- Fixed a project import issue in the LWRP template. +- Fixed the warnings that appear when you create new Unlit Shader Graphs using the Lightweight Render Pipeline. +- Fixed light attenuation precision on mobile platforms. +- Fixed split-screen rendering on mobile platforms. +- Fixed rendering when using an off-screen camera that renders to a depth texture. +- Fixed the exposed stencil render state in the renderer. +- Fixed the default layer mask so it's now applied to a depth pre-pass. +- Made several improvements and fixes to the render pass UI. +- Fixed artifacts that appeared due to precision errors in large scaled objects. +- Fixed an XR rendering issue where Unity required a depth texture. +- Fixed an issue that caused transparent objects to sort incorrectly. + +## [6.5.0] - 2019-03-07 +### Added +- You can now create a custom forward renderer by clicking on `Assets/Create/Rendering/Lightweight Render Pipeline/Forward Renderer`. This creates an Asset in your Project. You can add additional features to it and drag-n-drop the renderer to either the pipeline Asset or to a camera. +- You can now add `ScriptableRendererFeature` to the `ScriptableRenderer` to extend it with custom effects. A feature is an `ScriptableObject` that can be drag-n-dropped in the renderer and adds one or more `ScriptableRenderPass` to the renderer. +- `ScriptableRenderer` now exposes interface to configure lights. To do so, implement `SetupLights` when you create a new renderer. +- `ScriptableRenderer` now exposes interface to configure culling. To do so, implement `SetupCullingParameters` when you create a new renderer. +- `ScriptableRendererData` contains rendering resources for `ScriptableRenderer`. A renderer can be overridden globally for all cameras or on a per-camera basis. +- `ScriptableRenderPass` now has a `RenderPassEvents`. This controls where in the pipeline the render pass is added. +- `ScriptableRenderPass` now exposes `ConfigureTarget` and `ConfigureClear`. This allows the renderer to automatically figure out the currently active rendering targets. +- `ScriptableRenderPass` now exposes `Blit`. This performs a blit and sets the active render target in the renderer. +- `ScriptableRenderPass` now exposes `RenderPostProcessing`. This renders post-processing and sets the active render target in the renderer. +- `ScriptableRenderPass` now exposes `CreateDrawingSettings` as a helper for render passes that need to call `ScriptableRenderContext.DrawRenderers`. + +### Changed +- Removed `RegisterShaderPassName` from `ScriptableRenderPass`. Instead, `CreateDrawingSettings` now takes one or a list of `ShaderTagId`. +- Removed remaining experimental namespace from LWRP. All APIrelated to `ScriptableRenderer`, `ScriptableRenderPass`, and render pass injection is now out of preview. +- Removed `SetRenderTarget` from `ScriptableRenderPass`. You should never call it. Instead, call `ConfigureTarget`, and the renderer automatically sets up targets for you. +- Removed `RenderFullscreenQuad` from `ScriptableRenderer`. Use `CommandBuffer.DrawMesh` and `RenderingUtils.fullscreenMesh` instead. +- Removed `RenderPostProcess` from `ScriptableRenderer`. Use `ScriptableRenderPass.RenderPostProcessing` instead. +- Removed `postProcessingContext` property from `ScriptableRenderer`. This is now exposed in `RenderingUtils.postProcessingContext`. +- Removed `GetCameraClearFlag` from `ScriptableRenderer`. + +### Fixed +- Fixed y-flip in VR when post-processing is active. +- Fixed occlusion mesh for VR not rendering before rendering opaques. +- Enabling or disabling SRP Batcher in runtime works now. +- Fixed video player recorder when post-processing is enabled. + +## [6.4.0] - 2019-02-21 + +## [6.3.0] - 2019-02-18 + +## [6.2.0] - 2019-02-15 + +### Changed +- Code refactor: all macros with ARGS have been swapped with macros with PARAM. This is because the ARGS macros were incorrectly named. + +## [6.1.0] - 2019-02-13 + +## [6.0.0] - 2019-02-23 +### Added +- You can now implement a custom renderer for LWRP. To do so, implement an `IRendererData` that contains all resources used in rendering. Then create an `IRendererSetup` that creates and queues `ScriptableRenderPass`. Change the renderer type either in the Pipeline Asset or in the Camera Inspector. +- LWRP now uses the Unity recorder extension. You can use this to capture the output of Cameras. +- You can now inject a custom render pass before LWRP renders opaque objects. To do so, implement an `IBeforeRender` interface. +- Distortion support in all Particle Shaders. +- An upgrade system for LWRP Materials with `MaterialPostprocessor`. +- An upgrade path for Unlit shaders +- Tooltips for Shaders. +- SRP Batcher support for Particle Shaders. +- Docs for these Shaders: Baked Lit, Particles Lit, Particles Simple Lit, and Particles Unlit. +- LWRP now supports dynamic resolution scaling. The target platform must also support it. +- LWRP now includes version defines for both C# and Shaders in the format of `LWRP_X_Y_Z_OR_NEWER`. For example, `LWRP_5_3_0_OR_NEWER` defines version 5.3.0. +- The Terrain Lit Shader now samples Spherical Harmonics if you haven't baked any lightmaps for terrain. +- Added a __Priority__ option, which you can use to tweak the rendering order. This is similar to render queue in the built-in render pipeline. These Shaders now have this option: Lit, Simple Lit, Baked Lit, Unlit, and all three Particle Shaders. +- Added support for overriding terrain detail rendering shaders, via the render pipeline editor resources asset. + +### Changed +- You can now only initialize a camera by setting a Background Type. The supported options are Skybox, Solid Color, and Don't Care. +- LWRP now uses non-square shadowmap textures when it renders directional shadows with 2 shadow cascades. +- LWRP now uses RGB111110 as the HDR format on mobile devices, when this format is supported. +- Removed `IAfterDepthPrePass` interface. +- We’ve redesigned the Shader GUI. For example, all property names in Shaders are now inline across the board +- The Simple Lit Shader now has Smoothness, which can be stored in the alpha of specular or albedo maps. +- The Simple Lit and Particles Simple Lit Shaders now take shininess from the length (brightness) of the specular map. +- The __Double sided__ property is now __Render Face__. This means you can also do front face culling. +- Changed the docs for Lit Shader, Simple Lit Shader and Unlit Shader according to Shader GUI changes. +- When you create a new LWRP Asset, it will now be initialized with settings that favor performance on mobile platforms. +- Updated the [FAQ](faq.md) and the [Built-in/LWRP feature comparison table](lwrp-builtin-feature-comparison.md). + +### Fixed +- Several tweaks to reduce bandwidth consumption on mobile devices. +- The foldouts in the Lightweight Asset inspector UI now remember their state. +- Added missing meta file for GizmosRenderingPass.cs. +- Fixed artifacts when using multiple or Depth Only cameras. [Case 1072615](https://issuetracker.unity3d.com/issues/ios-using-multiple-cameras-in-the-scene-in-lightweight-render-pipeline-gives-corrupted-image-in-ios-device) +- Fixed a typo in ERROR_ON_UNSUPPORTED_FUNCTION() that was causing the shader compiler to run out of memory in GLES2. [Case 1104271](https://issuetracker.unity3d.com/issues/mobile-os-restarts-because-of-high-memory-usage-when-compiling-shaders-for-opengles2) +- LWRP now renders shadows on scaled objects correctly. [Case 1109017](https://issuetracker.unity3d.com/issues/scaled-objects-render-shadows-and-specularity-incorrectly-in-the-lwrp-on-device) +- LWRP now allows some Asset settings to be changed at runtime. [Case 1105552](https://issuetracker.unity3d.com/issues/lwrp-changing-render-scale-in-runtime-has-no-effect-since-lwrp-3-dot-3-0) +- Realtime shadows now work in GLES2. [Case 1087251](https://issuetracker.unity3d.com/issues/android-lwrp-no-real-time-light-and-shadows-using-gles2) +- Framedebugger now renders correctly when stepping through drawcalls. +- Cameras that request MSAA and Opaque Textures now use less frame bandwidth when they render. +- Fixed rendering in the gamma color space, so it doesn't appear darker. +- Particles SImple Lit and Particles Unlit Shaders now work correctly. +- __Soft Particles__ now work correctly. +- Camera fading for particles. +- Fixed a typo in the Unlit `IgnoreProjector` tag. +- Particles render in both eyes with stereo instancing +- Fixed specular issues on mobile. [case 1109017](https://issuetracker.unity3d.com/issues/scaled-objects-render-shadows-and-specularity-incorrectly-in-the-lwrp-on-device) +- Fixed issue causing LWRP to create MSAA framebuffer even when MSAA setting was disabled. +- Post-processing in mobile VR is now forced to be disabled. It was causing many rendering issues. +- Fixed Editor Previews breaking in Play Mode when VR is enabled. [Case 1109009](https://issuetracker.unity3d.com/issues/lwrp-editor-previews-break-in-play-mode-if-vr-is-enabled) +- A camera's HDR enable flag is now respected when rendering in XR. +- Terrain detail rendering now works correctly when LWRP is installed but inactive. + +## [5.2.0] - 2018-11-27 +### Added +- LWRP now handles blits that are required by the device when rendering to the backbuffer. +- You can now enable the SRP Batcher. To do so, go to the `Pipeline Asset`. Under `Advanced`, toggle `SRP Batcher`. + +### Changed +- Renamed shader variable `unity_LightIndicesOffsetAndCount` to `unity_PerObjectLightData`. +- Shader variables `unity_4LightIndices0` and `unity_4LightIndices1` are now declared as `unity_PerObjectLightIndices` array. + +## [5.1.0] - 2018-11-19 +### Added +- The user documentation for LWRP is now in this GitHub repo, instead of in the separate GitHub wiki. You can find the most up-to-date pages in the [TableOfContents.md](TableOfCotents.md) file. Pages not listed in that file are still in progress. + +### Changed +- The LWRP package is no longer in preview. +- LWRP built-in render passes are now internal. +- Changed namespace from `UnityEngine.Experimental.Rendering.LightweightPipeline` to `UnityEngine.Rendering.LWRP`. +- Changed namespace from `UnityEditor.Experimental.Rendering.LightweightPipeline` to `UnityEditor.Rendering.LWRP`. + +### Fixed +- LWRP now respects the iOS Player setting **Force hard shadows**. When you enable this setting, hardware filtering of shadows is disabled. +- Scene view mode now renders baked lightmaps correctly. [Case 1092227](https://issuetracker.unity3d.com/issues/lwrp-scene-view-modes-render-objects-black) +- Shadow bias calculations are now correct for both Shader Graph and Terrain shaders. +- Blit shader now ignores culling. +- When you select __Per Vertex__ option for __Additional Lights__, the __Per Object Limit__ option is not greyed out anymore. +- When you change camera viewport height to values above 1.0, the Unity Editor doesn't freeze anymore. [Case 1097497](https://issuetracker.unity3d.com/issues/macos-lwrp-editor-freezes-after-changing-cameras-viewport-rect-values) +- When you use AR with LWRP, the following error message is not displayed in the console anymore: "The camera list passed to the render pipeline is either null or empty." + +## [5.0.0-preview] - 2018-09-28 +### Added +- Added occlusion mesh rendering/hookup for VR +- You can now configure default depth and normal shadow bias values in the pipeline asset. +- You can now add the `LWRPAdditionalLightData` component to a `Light` to override the default depth and normal shadow bias. +- You can now log the amount of shader variants in your build. To do so, go to the `Pipeline Asset`. Under `Advanced`, select and set the `Shader Variant Log Level`. +### Changed +- Removed the `supportedShaderFeatures` property from LWRP core. The shader stripper now figures out which variants to strip based on the current assigned pipeline Asset in the Graphics settings. +### Fixed +- The following error does not appear in console anymore: ("Begin/End Profiler section mismatch") +- When you select a material with the Lit shader, this no longer causes the following error in the console: ("Material doesn't have..."). [case 1092354](https://fogbugz.unity3d.com/f/cases/1092354/) +- In the Simple Lit shader, per-vertex additional lights are now shaded properly. +- Shader variant stripping now works when you're building a Project with Cloud Build. This greatly reduces build times from Cloud Build. +- Dynamic Objects now receive lighting when the light mode is set to mixed. +- MSAA now works on Desktop platforms. +- The shadow bias value is now computed correctly for shadow cascades and different shadow resolutions. [case 1076285](https://issuetracker.unity3d.com/issues/lwrp-realtime-directional-light-shadow-maps-exhibit-artifacts) +- When you use __Area Light__ with LWRP, __Cast Shadows__ no longer overlaps with other UI elements in the Inspector. [case 1085363](https://issuetracker.unity3d.com/issues/inspector-area-light-cast-shadows-ui-option-is-obscured-by-render-mode-for-lwrp-regression-in-2018-dot-3a3) + +### Changed +Read/write XRGraphicsConfig -> Read-only XRGraphics interface to XRSettings. + +## [4.0.0-preview] - 2018-09-28 +### Added +- When you have enabled Gizmos, they now appear correctly in the Game view. +- Added requiresDepthPrepass field to RenderingData struct to tell if the runtime platform requires a depth prepass to generate a camera depth texture. +- The `RenderingData` struct now holds a reference to `CullResults`. +- When __HDR__ is enabled in the Camera but disabled in the Asset, an information box in the Camera Inspector informs you about it. +- When __MSAA__ is enabled in the Camera but disabled in the Asset, an information box in the Camera Inspector informs you about it. +- Enabled instancing on the terrain shader. +- Sorting of opaque objects now respects camera `opaqueSortMode` setting. +- Sorting of opaque objects disables front-to-back sorting flag, when camera settings allow that and the GPU has hidden surface removal. +- LWRP now has a Custom Light Explorer that suits its feature set. +- LWRP now supports Vertex Lit shaders for detail meshes on terrain. +- LWRP now has three interactive Autodesk shaders: Autodesk Interactive, Autodesk Interactive Masked and Autodesk Interactive Transparent. +- [Shader API] The `GetMainLight` and `GetAdditionalLight` functions can now compute shadow attenuation and store it in the new `shadowAttenuation` field in `LightData` struct. +- [Shader API] Added a `VertexPositionInputs` struct that contains vertex position in difference spaces (world, view, hclip). +- [Shader API] Added a `GetVertexPositionInputs` function to get an initialized `VertexPositionInputs`. +- [Shader API] Added a `GetPerObjectLightIndex` function to return the per-object index given a for-loop index. +- [Shader API] Added a `GetShadowCoord` function that takes a `VertexPositionInputs` as input. +- [ShaderLibrary] Added VertexNormalInputs struct that contains data for per-pixel normal computation. +- [ShaderLibrary] Added GetVertexNormalInputs function to return an initialized VertexNormalInputs. + +### Changed +- The `RenderingData` struct is now read-only. +- `ScriptableRenderer`always performs a Clear before calling `IRendererSetup::Setup.` +- `ScriptableRenderPass::Execute` no longer takes `CullResults` as input. Instead, use `RenderingData`as input, since that references `CullResults`. +- `IRendererSetup_Setup` no longer takes `ScriptableRenderContext` and `CullResults` as input. +- Shader includes are now referenced via package relative paths instead of via the deprecated shader export path mechanism https://docs.unity3d.com/2018.3/Documentation/ScriptReference/ShaderIncludePathAttribute.html. +- The LWRP Asset settings were re-organized to be more clear. +- Vertex lighting now controls if additional lights should be shaded per-vertex or per-pixel. +- Renamed all `Local Lights` nomenclature to `Additional Lights`. +- Changed shader naming to conform to our SRP shader code convention. +- [Shader API] Renamed `SpotAttenuation` function to `AngleAttenuation`. +- [Shader API] Renamed `_SHADOWS_ENABLED` keyword to `_MAIN_LIGHT_SHADOWS` +- [Shader API] Renamed `_SHADOWS_CASCADE` keyword to `_MAIN_LIGHT_SHADOWS_CASCADE` +- [Shader API] Renamed `_VERTEX_LIGHTS` keyword to `_ADDITIONAL_LIGHTS_VERTEX`. +- [Shader API] Renamed `_LOCAL_SHADOWS_ENABLED` to `_ADDITIONAL_LIGHT_SHADOWS` +- [Shader API] Renamed `GetLight` function to `GetAdditionalLight`. +- [Shader API] Renamed `GetPixelLightCount` function to `GetAdditionalLightsCount`. +- [Shader API] Renamed `attenuation` to `distanceAttenuation` in `LightData`. +- [Shader API] Renamed `GetLocalLightShadowStrength` function to `GetAdditionalLightShadowStrength`. +- [Shader API] Renamed `SampleScreenSpaceShadowMap` functions to `SampleScreenSpaceShadowmap`. +- [Shader API] Renamed `MainLightRealtimeShadowAttenuation` function to `MainLightRealtimeShadow`. +- [Shader API] Renamed light constants from `Directional` and `Local` to `MainLight` and `AdditionalLights`. +- [Shader API] Renamed `GetLocalLightShadowSamplingData` function to `GetAdditionalLightShadowSamplingData`. +- [Shader API] Removed OUTPUT_NORMAL macro. +- [Shader API] Removed `lightIndex` and `substractiveAttenuation` from `LightData`. +- [Shader API] Removed `ComputeShadowCoord` function. `GetShadowCoord` is provided instead. +- All `LightweightPipeline` references in API and classes are now named `LightweightRenderPipeline`. +- Files no longer have the `Lightweight` prefix. +- Renamed Physically Based shaders to `Lit`, `ParticlesLit`, and `TerrainLit`. +- Renamed Simple Lighting shaders to `SimpleLit`, and `ParticlesSimpleLit`. +- [ShaderLibrary] Renamed `InputSurfacePBR.hlsl`, `InputSurfaceSimple.hlsl`, and `InputSurfaceUnlit` to `LitInput.hlsl`, `SimpleLitInput.hlsl`, and `UnlitInput.hlsl`. These files were moved from the `ShaderLibrary` folder to the`Shaders`. +- [ShaderLibrary] Renamed `LightweightPassLit.hlsl` and `LightweightPassLitSimple.hlsl` to `LitForwardPass.hlsl` and `SimpleLitForwardPass.hlsl`. These files were moved from the `ShaderLibrary` folder to `Shaders`. +- [ShaderLibrary] Renamed `LightweightPassMetaPBR.hlsl`, `LightweightPassMetaSimple.hlsl` and `LighweightPassMetaUnlit` to `LitMetaPass.hlsl`, `SimpleLitMetaPass.hlsl` and `UnlitMetaPass.hlsl`. These files were moved from the `ShaderLibrary` folder to `Shaders`. +- [ShaderLibrary] Renamed `LightweightPassShadow.hlsl` to `ShadowCasterPass.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `LightweightPassDepthOnly.hlsl` to `DepthOnlyPass.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `InputSurfaceTerrain.hlsl` to `TerrainLitInput.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `LightweightPassLitTerrain.hlsl` to `TerrainLitPases.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `ParticlesPBR.hlsl` to `ParticlesLitInput.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `InputSurfacePBR.hlsl` to `LitInput.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `InputSurfaceUnlit.hlsl` to `UnlitInput.hlsl`. This file was moved to the `Shaders` folder. +- [ShaderLibrary] Renamed `InputBuiltin.hlsl` to `UnityInput.hlsl`. +- [ShaderLibrary] Renamed `LightweightPassMetaCommon.hlsl` to `MetaInput.hlsl`. +- [ShaderLibrary] Renamed `InputSurfaceCommon.hlsl` to `SurfaceInput.hlsl`. +- [ShaderLibrary] Removed LightInput struct and GetLightDirectionAndAttenuation. Use GetAdditionalLight function instead. +- [ShaderLibrary] Removed ApplyFog and ApplyFogColor functions. Use MixFog and MixFogColor instead. +- [ShaderLibrary] Removed TangentWorldToNormal function. Use TransformTangentToWorld instead. +- [ShaderLibrary] Removed view direction normalization functions. View direction should always be normalized per pixel for accurate results. +- [ShaderLibrary] Renamed FragmentNormalWS function to NormalizeNormalPerPixel. + +### Fixed +- If you have more than 16 lights in a scene, LWRP no longer causes random glitches while rendering lights. +- The Unlit shader now samples Global Illumination correctly. +- The Inspector window for the Unlit shader now displays correctly. +- Reduced GC pressure by removing several per-frame memory allocations. +- The tooltip for the the camera __MSAA__ property now appears correctly. +- Fixed multiple C# code analysis rule violations. +- The fullscreen mesh is no longer recreated upon every call to `ScriptableRenderer.fullscreenMesh`. + +## [3.3.0-preview] - 2018-01-01 +### Added +- Added callbacks to LWRP that can be attached to a camera (IBeforeCameraRender, IAfterDepthPrePass, IAfterOpaquePass, IAfterOpaquePostProcess, IAfterSkyboxPass, IAfterTransparentPass, IAfterRender) + +###Changed +- Clean up LWRP creation of render textures. If we are not going straight to screen ensure that we create both depth and color targets. +- UNITY_DECLARE_FRAMEBUFFER_INPUT and UNITY_READ_FRAMEBUFFER_INPUT macros were added. They are necessary for reading transient attachments. +- UNITY_MATRIX_I_VP is now defined. +- Renamed LightweightForwardRenderer to ScriptableRenderer. +- Moved all light constants to _LightBuffer CBUFFER. Now _PerCamera CBUFFER contains all other per camera constants. +- Change real-time attenuation to inverse square. +- Change attenuation for baked GI to inverse square, to match real-time attenuation. +- Small optimization in light attenuation shader code. + +### Fixed +- Lightweight Unlit shader UI doesn't throw an error about missing receive shadow property anymore. + +## [3.2.0-preview] - 2018-01-01 +### Changed +- Receive Shadows property is now exposed in the material instead of in the renderer. +- The UI for Lightweight asset has been updated with new categories. A more clean structure and foldouts has been added to keep things organized. + +### Fixed +- Shadow casters are now properly culled per cascade. (case 1059142) +- Rendering no longer breaks when Android platform is selected in Build Settings. (case 1058812) +- Scriptable passes no longer have missing material references. Now they access cached materials in the renderer.(case 1061353) +- When you change a Shadow Cascade option in the Pipeline Asset, this no longer warns you that you've exceeded the array size for the _WorldToShadow property. +- Terrain shader optimizations. + +## [3.1.0-preview] - 2018-01-01 + +### Fixed +- Fixed assert errors caused by multi spot lights +- Fixed LWRP-DirectionalShadowConstantBuffer params setting + +## [3.0.0-preview] - 2018-01-01 +### Added +- Added camera additional data component to control shadows, depth and color texture. +- pipeline now uses XRSEttings.eyeTextureResolutionScale as renderScale when in XR. +- New pass architecture. Allows for custom passes to be written and then used on a per camera basis in LWRP + +### Changed +- Shadow rendering has been optimized for the Mali Utgard architecture by removing indexing and avoiding divisions for orthographic projections. This reduces the frame time by 25% on the Overdraw benchmark. +- Removed 7x7 tent filtering when using cascades. +- Screenspace shadow resolve is now only done when rendering shadow cascades. +- Updated the UI for the Lighweight pipeline asset. +- Update assembly definitions to output assemblies that match Unity naming convention (Unity.*). + +### Fixed +- Post-processing now works with VR on PC. +- PS4 compiler error +- Fixed VR multiview rendering by forcing MSAA to be off. There's a current issue in engine that breaks MSAA and Texture2DArray. +- Fixed UnityPerDraw CB layout +- GLCore compute buffer compiler error +- Occlusion strength not being applied on LW standard shaders +- CopyDepth pass is being called even when a depth from prepass is available +- GLES2 shader compiler error in IntegrationTests +- Can't set RenderScale and ShadowDistance by script +- VR Single Pass Instancing shadows +- Fixed compilation errors on platforms with limited XRSetting support. + +## [2.0.0-preview] - 2018-01-01 + +### Added +- Explicit render target load/store actions were added to improve tile utilization +- Camera opaque color can be requested on the pipeline asset. It can be accessed in the shader by defining a _CameraOpaqueTexture. This can be used as an alternative to GrabPass. +- Dynamic Batching can be enabled in the pipeline asset +- Pipeline now strips unused or invalid variants and passes based on selected pipeline capabilities in the asset. This reduces build and memory consuption on target. +- Shader stripping settings were added to pipeline asset + +### Changed +#### Pipeline +- Pipeline code is now more modular and extensible. A ForwardRenderer class is initialized by the pipeline with RenderingData and it's responsible for enqueueing and executing passes. In the future pluggable renderers will be supported. +- On mobile 1 directional light + up to 4 local lights (point or spot) are computed +- On other platforms 1 directional light + up to 8 local lights are computed +- Multiple shadow casting lights are supported. Currently only 1 directional + 4 spots light shadows. +#### Shading Framework +- Directional Lights are always considered a main light in shader. They have a fast shading path with no branching and no indexing. +- GetMainLight() is provided in shader to initialize Light struct with main light shading data. +- Directional lights have a dedicated shadowmap for performance reasons. Shadow coord always comes from interpolator. +- MainLigthRealtimeShadowAttenuation(float4 shadowCoord) is provided to compute main light realtime shadows. +- Spot and Point lights are always shaded in the light loop. Branching on uniform and indexing happens when shading them. +- GetLight(half index, float3 positionWS) is provided in shader to initialize Light struct for spot and point lights. +- Spot light shadows are baked into a single shadow atlas. +- Shadow coord for spot lights is always computed on fragment. +- Use LocalLightShadowAttenuation(int lightIndex, float3 positionWS) to comppute realtime shadows for spot lights. + +### Fixed +- Issue that was causing VR on Android to render black +- Camera viewport issues +- UWP build issues +- Prevent nested camera rendering in the pipeline + +## [1.1.4-preview] - 2018-01-01 + +### Added + - Terrain and grass shaders ported + - Updated materials and shader default albedo and specular color to midgrey. + - Exposed _ScaledScreenParams to shader. It works the same as _ScreenParams but takes pipeline RenderScale into consideration + - Performance Improvements in mobile + +### Fixed + - SRP Shader library issue that was causing all constants to be highp in mobile + - shader error that prevented LWRP to build to UWP + - shader compilation errors in Linux due to case sensitive includes + - Rendering Texture flipping issue + - Standard Particles shader cutout and blending modes + - crash caused by using projectors + - issue that was causing Shadow Strength to not be computed on mobile + - Material Upgrader issue that caused editor to SoftLocks + - GI in Unlit shader + - Null reference in the Unlit material shader GUI + +## [1.1.2-preview] - 2018-01-01 + +### Changed + - Performance improvements in mobile + +### Fixed + - Shadows on GLES 2.0 + - CPU performance regression in shadow rendering + - Alpha clip shadow issues + - Unmatched command buffer error message + - Null reference exception caused by missing resource in LWRP + - Issue that was causing Camera clear flags was being ignored in mobile + + +## [1.1.1-preview] - 2018-01-01 + +### Added + - Added Cascade Split selection UI + - Added SHADER_HINT_NICE_QUALITY. If user defines this to 1 in the shader Lightweight pipeline will favor quality even on mobile platforms. + +### Changed + - Shadowmap uses 16bit format instead of 32bit. + - Small shader performance improvements + +### Fixed + - Subtractive Mode + - Shadow Distance does not accept negative values anymore + + +## [0.1.24] - 2018-01-01 + +### Added + - Added Light abstraction layer on lightweight shader library. + - Added HDR global setting on pipeline asset. + - Added Soft Particles settings on pipeline asset. + - Ported particles shaders to SRP library + +### Changed + - HDR RT now uses what format is configured in Tier settings. + - Refactored lightweight standard shaders and shader library to improve ease of use. + - Optimized tile LOAD op on mobile. + - Reduced GC pressure + - Reduced shader variant count by ~56% by improving fog and lightmap keywords + - Converted LW shader library files to use real/half when necessary. + +### Fixed + - Realtime shadows on OpenGL + - Shader compiler errors in GLES 2.0 + - Issue sorting issues when BeforeTransparent custom fx was enabled. + - VR single pass rendering. + - Viewport rendering issues when rendering to backbuffer. + - Viewport rendering issues when rendering to with MSAA turned off. + - Multi-camera rendering. + +## [0.1.23] - 2018-01-01 + +### Added + - UI Improvements (Rendering features not supported by LW are hidden) + +### Changed + - Shaders were ported to the new SRP shader library. + - Constant Buffer refactor to use new Batcher + - Shadow filtering and bias improved. + - Pipeline now updates color constants in gamma when in Gamma colorspace. + - Optimized ALU and CB usage on Shadows. + - Reduced shader variant count by ~33% by improving shadow and light classification keywords + - Default resources were removed from the pipeline asset. + +### Fixed + - Fixed shader include path when using SRP from package manager. + - Fixed spot light attenuation to match Unity Built-in pipeline. + - Fixed depth pre-pass clearing issue. + +## [0.1.12] - 2018-01-01 + +### Added + - Standard Unlit shader now has an option to sample GI. + - Added Material Upgrader for stock Unity Mobile and Legacy Shaders. + - UI improvements + +### Changed +- Realtime shadow filtering was improved. + +### Fixed + - Fixed an issue that was including unreferenced shaders in the build. + - Fixed a null reference caused by Particle System component lights. diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta index e097ab9..255392c 100644 --- a/CHANGELOG.md.meta +++ b/CHANGELOG.md.meta @@ -1,7 +1,7 @@ -fileFormatVersion: 2 -guid: 16b5d2a7d862f49ffb9453600e8ee776 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 16b5d2a7d862f49ffb9453600e8ee776 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor.meta b/Editor.meta index 018fbd3..db65d14 100644 --- a/Editor.meta +++ b/Editor.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 53c20613ce8ac478dba8507359e02516 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 53c20613ce8ac478dba8507359e02516 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D.meta b/Editor/2D.meta index 6c3000b..42c7ef9 100644 --- a/Editor/2D.meta +++ b/Editor/2D.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: b3fb8b56aca55544ca9b8d53bc19e031 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b3fb8b56aca55544ca9b8d53bc19e031 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs b/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs index 89f748b..1ade872 100644 --- a/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs +++ b/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs @@ -1,11 +1,11 @@ -namespace UnityEditor.Experimental.Rendering.Universal -{ - [CustomEditor(typeof(UnityEngine.Experimental.Rendering.Universal.CinemachineUniversalPixelPerfect)), CanEditMultipleObjects] - internal class CinemachineUniversalPixelPerfectEditor : Editor - { - public override void OnInspectorGUI() - { - EditorGUILayout.HelpBox("This Cinemachine extension is now deprecated and doesn't function properly. Instead, use the one from Cinemachine v2.4.0 or newer.", MessageType.Error); - } - } -} +namespace UnityEditor.Rendering.Universal +{ + [CustomEditor(typeof(UnityEngine.Rendering.Universal.CinemachineUniversalPixelPerfect)), CanEditMultipleObjects] + internal class CinemachineUniversalPixelPerfectEditor : Editor + { + public override void OnInspectorGUI() + { + EditorGUILayout.HelpBox("This Cinemachine extension is now deprecated and doesn't function properly. Instead, use the one from Cinemachine v2.4.0 or newer.", MessageType.Error); + } + } +} diff --git a/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs.meta b/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs.meta index 227e00b..7e62784 100644 --- a/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs.meta +++ b/Editor/2D/CinemachineUniversalPixelPerfectEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 3fccaa742ce23c84d99d542d72ccbc74 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 3fccaa742ce23c84d99d542d72ccbc74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/CompositeShadowCaster2DEditor.cs b/Editor/2D/CompositeShadowCaster2DEditor.cs index a315d63..c23947c 100644 --- a/Editor/2D/CompositeShadowCaster2DEditor.cs +++ b/Editor/2D/CompositeShadowCaster2DEditor.cs @@ -1,17 +1,13 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; - - -namespace UnityEditor.Experimental.Rendering.Universal -{ - - [CustomEditor(typeof(CompositeShadowCaster2D))] - internal class CompositeShadowCaster2DEditor : Editor - { - public override void OnInspectorGUI() - { - } - } -} +using UnityEngine.Rendering.Universal; + + +namespace UnityEditor.Rendering.Universal +{ + [CustomEditor(typeof(CompositeShadowCaster2D))] + internal class CompositeShadowCaster2DEditor : Editor + { + public override void OnInspectorGUI() + { + } + } +} diff --git a/Editor/2D/CompositeShadowCaster2DEditor.cs.meta b/Editor/2D/CompositeShadowCaster2DEditor.cs.meta index 25026ba..af4b1ef 100644 --- a/Editor/2D/CompositeShadowCaster2DEditor.cs.meta +++ b/Editor/2D/CompositeShadowCaster2DEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 0bc972c43bf3a8347aee5ba065c03157 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 0bc972c43bf3a8347aee5ba065c03157 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Shadow.meta b/Editor/2D/Converter.meta similarity index 73% rename from Editor/Shadow.meta rename to Editor/2D/Converter.meta index cb887f6..39e78dc 100644 --- a/Editor/Shadow.meta +++ b/Editor/2D/Converter.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 79381f0a1a24d284cb7d726fde8b3cca -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 5361c774211d0234c94d0161651a5407 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Converter/BuiltInToURP2DConverterContainer.cs b/Editor/2D/Converter/BuiltInToURP2DConverterContainer.cs new file mode 100644 index 0000000..30381aa --- /dev/null +++ b/Editor/2D/Converter/BuiltInToURP2DConverterContainer.cs @@ -0,0 +1,8 @@ +namespace UnityEditor.Rendering.Universal.Converters +{ + internal sealed class BuiltInToURP2DConverterContainer : RenderPipelineConverterContainer + { + public override string name => "Convert Built-in to 2D (URP)"; + public override string info => "Converter performs the following tasks:\n* Converts project elements from the Built-in Render Pipeline to 2D URP."; + } +} diff --git a/Runtime/2D/Light2DStub.cs.meta b/Editor/2D/Converter/BuiltInToURP2DConverterContainer.cs.meta similarity index 80% rename from Runtime/2D/Light2DStub.cs.meta rename to Editor/2D/Converter/BuiltInToURP2DConverterContainer.cs.meta index b2f2f60..e213aac 100644 --- a/Runtime/2D/Light2DStub.cs.meta +++ b/Editor/2D/Converter/BuiltInToURP2DConverterContainer.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 6b1b9051bda976648ac2ccca324820f0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 5efd56ae74d26a24f88c656137e3c10e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Converter/BuiltInToURP2DMaterialUpgrader.cs b/Editor/2D/Converter/BuiltInToURP2DMaterialUpgrader.cs new file mode 100644 index 0000000..26caffa --- /dev/null +++ b/Editor/2D/Converter/BuiltInToURP2DMaterialUpgrader.cs @@ -0,0 +1,136 @@ +using System; +using System.IO; +using System.Collections.Generic; +using UnityEditor.Rendering.Universal.Converters; +using UnityEngine; +using UnityEngine.Rendering.Universal; + + +namespace UnityEditor.Rendering.Universal +{ + internal sealed class BuiltInToURP2DMaterialUpgrader : RenderPipelineConverter + { + public override string name => "Material and Material Reference Upgrade"; + public override string info => "This will upgrade all materials and material references."; + public override int priority => -1000; + public override Type container => typeof(BuiltInToURP2DConverterContainer); + + List m_AssetsToConvert = new List(); + + Material m_SpriteLitDefaultMat; + Material m_SpritesDefaultMat; + Material m_SpritesMaskMat; + Material m_SpriteMaskDefaultMat; + Shader m_SpriteLitDefaultShader; + Shader m_SpritesDefaultShader; + + string m_SpritesDefaultShaderId; + string m_SpritesDefaultMatId; + string m_SpritesMaskMatId; + + void UpgradeGameObject(GameObject go) + { + Renderer[] renderers = go.GetComponentsInChildren(); + foreach (Renderer renderer in renderers) + { + if (!PrefabUtility.IsPartOfPrefabInstance(renderer)) + { + int materialCount = renderer.sharedMaterials.Length; + Material[] newMaterials = new Material[materialCount]; + bool updateMaterials = false; + + for (int matIndex = 0; matIndex < materialCount; matIndex++) + { + if (renderer.sharedMaterials[matIndex] == m_SpritesDefaultMat) + { + newMaterials[matIndex] = m_SpriteLitDefaultMat; + updateMaterials = true; + } + else if (renderer.sharedMaterials[matIndex] == m_SpritesMaskMat) + { + newMaterials[matIndex] = m_SpriteMaskDefaultMat; + updateMaterials = true; + } + else + newMaterials[matIndex] = renderer.sharedMaterials[matIndex]; + } + + if (updateMaterials) + renderer.sharedMaterials = newMaterials; + } + } + } + + public override void OnInitialize(InitializeConverterContext context, Action callback) + { + Renderer2DData data = Light2DEditorUtility.GetRenderer2DData(); + if (data != null) + m_SpriteLitDefaultMat = data.GetDefaultMaterial(DefaultMaterialType.Sprite); + else + m_SpriteLitDefaultMat = AssetDatabase.LoadAssetAtPath("Packages/com.unity.render-pipelines.universal/Runtime/Materials/Sprite-Lit-Default.mat"); + + m_SpritesDefaultMat = AssetDatabase.GetBuiltinExtraResource("Sprites-Default.mat"); + m_SpriteMaskDefaultMat = AssetDatabase.LoadAssetAtPath("Packages/com.unity.render-pipelines.universal/Runtime/Materials/SpriteMask-Default.mat"); + m_SpritesMaskMat = AssetDatabase.GetBuiltinExtraResource("Sprites-Mask.mat"); + m_SpriteLitDefaultShader = m_SpriteLitDefaultMat.shader; + m_SpritesDefaultShader = m_SpritesDefaultMat.shader; + m_SpritesDefaultShaderId = URP2DConverterUtility.GetObjectIDString(m_SpritesDefaultShader); + m_SpritesDefaultMatId = URP2DConverterUtility.GetObjectIDString(m_SpritesDefaultMat); + m_SpritesMaskMatId = URP2DConverterUtility.GetObjectIDString(m_SpritesMaskMat); + + string[] allAssetPaths = AssetDatabase.GetAllAssetPaths(); + + foreach (string path in allAssetPaths) + { + if (URP2DConverterUtility.IsMaterialPath(path, m_SpritesDefaultShaderId) || URP2DConverterUtility.IsPrefabOrScenePath(path, new string[] { m_SpritesDefaultMatId, m_SpritesMaskMatId })) + { + ConverterItemDescriptor desc = new ConverterItemDescriptor() + { + name = Path.GetFileNameWithoutExtension(path), + info = path, + warningMessage = String.Empty, + helpLink = String.Empty + }; + + // Each converter needs to add this info using this API. + m_AssetsToConvert.Add(path); + context.AddAssetToConvert(desc); + } + } + + callback.Invoke(); + } + + public override void OnRun(ref RunItemContext context) + { + string result = string.Empty; + string ext = Path.GetExtension(context.item.descriptor.info); + if (ext == ".prefab") + result = URP2DConverterUtility.UpgradePrefab(context.item.descriptor.info, UpgradeGameObject); + else if (ext == ".unity") + URP2DConverterUtility.UpgradeScene(context.item.descriptor.info, UpgradeGameObject); + else if (ext == ".mat") + URP2DConverterUtility.UpgradeMaterial(context.item.descriptor.info, m_SpritesDefaultShader, m_SpriteLitDefaultShader); + + if (result != string.Empty) + { + context.didFail = true; + context.info = result; + } + else + { + context.hasConverted = true; + } + } + + public override void OnClicked(int index) + { + EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(m_AssetsToConvert[index])); + } + + public override void OnPostRun() + { + Resources.UnloadUnusedAssets(); + } + } +} diff --git a/Editor/2D/Renderer2DUpgrader.cs.meta b/Editor/2D/Converter/BuiltInToURP2DMaterialUpgrader.cs.meta similarity index 80% rename from Editor/2D/Renderer2DUpgrader.cs.meta rename to Editor/2D/Converter/BuiltInToURP2DMaterialUpgrader.cs.meta index b4a5717..5f21982 100644 --- a/Editor/2D/Renderer2DUpgrader.cs.meta +++ b/Editor/2D/Converter/BuiltInToURP2DMaterialUpgrader.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: cec659aa9f17b544c841b8cc7b22cc93 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 265ffa21109c3e74b82d8703941368db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Converter/ParametricToFreeformLightUpgrader.cs b/Editor/2D/Converter/ParametricToFreeformLightUpgrader.cs new file mode 100644 index 0000000..b0bb851 --- /dev/null +++ b/Editor/2D/Converter/ParametricToFreeformLightUpgrader.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; +using System.Collections.Generic; +using UnityEditor.Rendering.Universal.Converters; +using UnityEngine; +using UnityEngine.Rendering.Universal; + + +namespace UnityEditor.Rendering.Universal +{ + internal sealed class ParametricToFreeformLightUpgrader : RenderPipelineConverter + { + const float k_EnscribedSquareDiagonalLength = 0.70710678118654752440084436210485f; + + public override string name => "Parametric to Freeform Light Upgrade"; + public override string info => "This will upgrade all parametric lights to freeform lights."; + public override int priority => -1000; + public override Type container => typeof(UpgradeURP2DAssetsContainer); + + List m_AssetsToConvert = new List(); + + string m_Light2DId; + + public static void UpgradeParametricLight(Light2D light) + { + if (light.lightType == (Light2D.LightType)Light2D.DeprecatedLightType.Parametric) + { + light.lightType = Light2D.LightType.Freeform; + + float radius = light.shapeLightParametricRadius; + float angle = light.shapeLightParametricAngleOffset; + int sides = light.shapeLightParametricSides; + + var angleOffset = Mathf.PI / 2.0f + Mathf.Deg2Rad * angle; + if (sides < 3) + { + radius = k_EnscribedSquareDiagonalLength * radius; + sides = 4; + } + + if (sides == 4) + { + angleOffset = Mathf.PI / 4.0f + Mathf.Deg2Rad * angle; + } + + var radiansPerSide = 2 * Mathf.PI / sides; + var min = new Vector3(float.MaxValue, float.MaxValue, 0); + var max = new Vector3(float.MinValue, float.MinValue, 0); + + + Vector3[] shapePath = new Vector3[sides]; + for (var i = 0; i < sides; i++) + { + var endAngle = (i + 1) * radiansPerSide; + var extrudeDir = new Vector3(Mathf.Cos(endAngle + angleOffset), Mathf.Sin(endAngle + angleOffset), 0); + var endPoint = radius * extrudeDir; + + shapePath[i] = endPoint; + } + + light.shapePath = shapePath; + light.UpdateMesh(true); + } + } + + void UpgradeGameObject(GameObject go) + { + Light2D[] lights = go.GetComponentsInChildren(); + foreach (Light2D light in lights) + { + if (light.lightType == Light2D.LightType.Parametric && !PrefabUtility.IsPartOfPrefabInstance(light)) + UpgradeParametricLight(light); + } + } + + public override void OnInitialize(InitializeConverterContext context, Action callback) + { + string[] allAssetPaths = AssetDatabase.GetAllAssetPaths(); + + foreach (string path in allAssetPaths) + { + if (URP2DConverterUtility.IsPrefabOrScenePath(path, "m_LightType: 0")) + { + ConverterItemDescriptor desc = new ConverterItemDescriptor() + { + name = Path.GetFileNameWithoutExtension(path), + info = path, + warningMessage = String.Empty, + helpLink = String.Empty + }; + + // Each converter needs to add this info using this API. + m_AssetsToConvert.Add(path); + context.AddAssetToConvert(desc); + } + } + + callback.Invoke(); + } + + public override void OnRun(ref RunItemContext context) + { + string result = string.Empty; + string ext = Path.GetExtension(context.item.descriptor.info); + if (ext == ".prefab") + result = URP2DConverterUtility.UpgradePrefab(context.item.descriptor.info, UpgradeGameObject); + else if (ext == ".unity") + URP2DConverterUtility.UpgradeScene(context.item.descriptor.info, UpgradeGameObject); + + if (result != string.Empty) + { + context.didFail = true; + context.info = result; + } + else + { + context.hasConverted = true; + } + } + + public override void OnClicked(int index) + { + EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(m_AssetsToConvert[index])); + } + + public override void OnPostRun() + { + Resources.UnloadUnusedAssets(); + } + } +} diff --git a/Editor/Shadow/ShadowCascadeSplitGUI.cs.meta b/Editor/2D/Converter/ParametricToFreeformLightUpgrader.cs.meta similarity index 80% rename from Editor/Shadow/ShadowCascadeSplitGUI.cs.meta rename to Editor/2D/Converter/ParametricToFreeformLightUpgrader.cs.meta index 4822a52..ab98d78 100644 --- a/Editor/Shadow/ShadowCascadeSplitGUI.cs.meta +++ b/Editor/2D/Converter/ParametricToFreeformLightUpgrader.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: afa3cbf2c424d2d489b86e7e6c4e907e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 5f5877a9138882a4095ba0e997d19644 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Converter/URP2DConverterUtility.cs b/Editor/2D/Converter/URP2DConverterUtility.cs new file mode 100644 index 0000000..90c6f5a --- /dev/null +++ b/Editor/2D/Converter/URP2DConverterUtility.cs @@ -0,0 +1,141 @@ +using System; +using UnityEngine; +using UnityEditor; +using System.IO; +using UnityEditor.SceneManagement; +using UnityEngine.SceneManagement; + +internal static class URP2DConverterUtility +{ + public static bool IsMaterialPath(string path, string id) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException(nameof(path)); + + if (path.StartsWith("Packages")) + return false; + + if (path.EndsWith(".mat")) + return URP2DConverterUtility.DoesFileContainString(path, new string[] { id }); + + return false; + } + + public static bool IsPrefabOrScenePath(string path, string[] ids) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException(nameof(path)); + + if (path.StartsWith("Packages")) + return false; + + if (path.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".unity", StringComparison.OrdinalIgnoreCase)) + return URP2DConverterUtility.DoesFileContainString(path, ids); + + return false; + } + + public static bool IsPrefabOrScenePath(string path, string id) + { + return IsPrefabOrScenePath(path, new string[] { id }); + } + + public static bool DoesFileContainString(string path, string[] strs) + { + if (strs != null && strs.Length > 0) + { + using (StreamReader file = File.OpenText(path)) + { + string line; + while ((line = file.ReadLine()) != null) + { + for (int i = 0; i < strs.Length; i++) + { + if (line.Contains(strs[i])) + return true; + } + } + } + } + + return false; + } + + public static string UpgradePrefab(string path, Action objectUpgrader) + { + UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(path); + + int firstIndex = 0; + for (int i = 0; i < objects.Length; i++) + { + if (objects[i] as GameObject) + { + firstIndex = i; + break; + } + } + + // There should be no need to check this as we have already determined that there is something that needs upgrading + if (!PrefabUtility.IsPartOfImmutablePrefab(objects[firstIndex])) + { + for (int objIndex = 0; objIndex < objects.Length; objIndex++) + { + GameObject go = objects[objIndex] as GameObject; + if (go != null) + { + objectUpgrader(go); + } + } + + GameObject asset = objects[firstIndex] as GameObject; + PrefabUtility.SavePrefabAsset(asset.transform.root.gameObject); + + return string.Empty; + } + + return "Unable to modify an immutable prefab"; + } + + public static void UpgradeScene(string path, Action objectUpgrader) + { + Scene scene = new Scene(); + bool openedByUser = false; + for (int i = 0; i < SceneManager.sceneCount && !openedByUser; i++) + { + scene = SceneManager.GetSceneAt(i); + if (path == scene.path) + openedByUser = true; + } + + if (!openedByUser) + scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive); + + GameObject[] gameObjects = scene.GetRootGameObjects(); + foreach (GameObject go in gameObjects) + objectUpgrader(go); + + EditorSceneManager.SaveScene(scene); + if (!openedByUser) + EditorSceneManager.CloseScene(scene, true); + } + + public static void UpgradeMaterial(string path, Shader oldShader, Shader newShader) + { + Material material = AssetDatabase.LoadAssetAtPath(path); + if (material.shader == oldShader) + material.shader = newShader; + + GUID guid = AssetDatabase.GUIDFromAssetPath(path); + AssetDatabase.SaveAssetIfDirty(guid); + } + + public static string GetObjectIDString(UnityEngine.Object obj) + { + string guid; + long localId; + if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj.GetInstanceID(), out guid, out localId)) + return "fileID: " + localId + ", guid: " + guid; + + return null; + } +} diff --git a/Editor/ForwardRendererDataEditor.cs.meta b/Editor/2D/Converter/URP2DConverterUtility.cs.meta similarity index 80% rename from Editor/ForwardRendererDataEditor.cs.meta rename to Editor/2D/Converter/URP2DConverterUtility.cs.meta index f43c8ed..4473850 100644 --- a/Editor/ForwardRendererDataEditor.cs.meta +++ b/Editor/2D/Converter/URP2DConverterUtility.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 83bc10a7c2ad648febccee3b43d25f20 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 4d81aa6b4f52f5a46a02e0957a23f550 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Converter/UpgradeURP2DAssetsContainer.cs b/Editor/2D/Converter/UpgradeURP2DAssetsContainer.cs new file mode 100644 index 0000000..e996c31 --- /dev/null +++ b/Editor/2D/Converter/UpgradeURP2DAssetsContainer.cs @@ -0,0 +1,8 @@ +namespace UnityEditor.Rendering.Universal.Converters +{ + internal sealed class UpgradeURP2DAssetsContainer : RenderPipelineConverterContainer + { + public override string name => "Upgrade 2D (URP) Assets"; + public override string info => "Converter performs the following tasks:\n* Upgrades assets from earlier 2D URP versions to the current 2D URP version."; + } +} diff --git a/Editor/2D/Converter/UpgradeURP2DAssetsContainer.cs.meta b/Editor/2D/Converter/UpgradeURP2DAssetsContainer.cs.meta new file mode 100644 index 0000000..ae9ae2d --- /dev/null +++ b/Editor/2D/Converter/UpgradeURP2DAssetsContainer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21a217258058bd347b67dccad871fe1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/FreeformPathPresets.cs b/Editor/2D/FreeformPathPresets.cs new file mode 100644 index 0000000..0af7b77 --- /dev/null +++ b/Editor/2D/FreeformPathPresets.cs @@ -0,0 +1,66 @@ +using UnityEngine; + + +namespace UnityEditor.Rendering.Universal +{ + internal static class FreeformPathPresets + { + public static Vector3[] CreateSquare() + { + Vector3[] returnPath = new Vector3[4] + { + new Vector3(-0.5f, -0.5f), + new Vector3(0.5f, -0.5f), + new Vector3(0.5f, 0.5f), + new Vector3(-0.5f, 0.5f) + }; + + return returnPath; + } + + public static Vector3[] CreateIsometricDiamond() + { + Vector3[] returnPath = new Vector3[4] + { + new Vector3(-0.5f, 0.0f), + new Vector3(0.0f, -0.25f), + new Vector3(0.5f, 0.0f), + new Vector3(0.0f, 0.25f) + }; + + return returnPath; + } + + private static Vector3[] CreateShape(int vertices, float angleOffset) + { + Vector3[] returnPath = new Vector3[vertices]; + const float kRadius = 0.5f; + + for (int i = 0; i < vertices; i++) + { + float angle = ((float)i * 2 * Mathf.PI / (float)vertices) + angleOffset; + float x = kRadius * Mathf.Cos(angle); + float y = kRadius * Mathf.Sin(angle); + + returnPath[i] = new Vector3(x, y); + } + + return returnPath; + } + + public static Vector3[] CreateCircle() + { + return CreateShape(32, 0); + } + + public static Vector3[] CreateHexagonFlatTop() + { + return CreateShape(6, 0); + } + + public static Vector3[] CreateHexagonPointedTop() + { + return CreateShape(6, 0.5f * Mathf.PI); + } + } +} diff --git a/Editor/2D/FreeformPathPresets.cs.meta b/Editor/2D/FreeformPathPresets.cs.meta new file mode 100644 index 0000000..8215e0d --- /dev/null +++ b/Editor/2D/FreeformPathPresets.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 258887e488db43041a92d45ddb4f2a4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Light2DEditor.cs b/Editor/2D/Light2DEditor.cs index 3c749fa..a8c50fc 100644 --- a/Editor/2D/Light2DEditor.cs +++ b/Editor/2D/Light2DEditor.cs @@ -1,650 +1,831 @@ -using System.Collections.Generic; -using System.Linq; -using UnityEditor.EditorTools; -using UnityEditor.Experimental.Rendering.Universal.Path2D; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - [CustomEditor(typeof(Light2D))] - [CanEditMultipleObjects] - internal class Light2DEditor : PathComponentEditor - { - [EditorTool("Edit Freeform Shape", typeof(Light2D))] - class FreeformShapeTool : PathEditorTool - { - const string k_ShapePath = "m_ShapePath"; - - public override bool IsAvailable() - { - var light = target as Light2D; - - if (light == null) - return false; - else - return base.IsAvailable() && light.lightType == Light2D.LightType.Freeform; - } - - protected override IShape GetShape(Object target) - { - return (target as Light2D).shapePath.ToPolygon(false); - } - - protected override void SetShape(ScriptablePath shapeEditor, SerializedObject serializedObject) - { - serializedObject.Update(); - - var pointsProperty = serializedObject.FindProperty(k_ShapePath); - pointsProperty.arraySize = shapeEditor.pointCount; - - for (var i = 0; i < shapeEditor.pointCount; ++i) - pointsProperty.GetArrayElementAtIndex(i).vector3Value = shapeEditor.GetPoint(i).position; - - ((Light2D)(serializedObject.targetObject)).UpdateMesh(); - - // This is untracked right now... - serializedObject.ApplyModifiedProperties(); - } - } - - private static class Styles - { - public static Texture lightCapTopRight = Resources.Load("LightCapTopRight"); - public static Texture lightCapTopLeft = Resources.Load("LightCapTopLeft"); - public static Texture lightCapBottomLeft = Resources.Load("LightCapBottomLeft"); - public static Texture lightCapBottomRight = Resources.Load("LightCapBottomRight"); - public static Texture lightCapUp = Resources.Load("LightCapUp"); - public static Texture lightCapDown = Resources.Load("LightCapDown"); - - public static GUIContent lightTypeParametric = new GUIContent("Parametric", Resources.Load("InspectorIcons/ParametricLight") as Texture); - public static GUIContent lightTypeFreeform = new GUIContent("Freeform", Resources.Load("InspectorIcons/FreeformLight") as Texture); - public static GUIContent lightTypeSprite = new GUIContent("Sprite", Resources.Load("InspectorIcons/SpriteLight") as Texture); - public static GUIContent lightTypePoint = new GUIContent("Point", Resources.Load("InspectorIcons/PointLight") as Texture); - public static GUIContent lightTypeGlobal = new GUIContent("Global", Resources.Load("InspectorIcons/GlobalLight") as Texture); - public static GUIContent[] lightTypeOptions = new GUIContent[] { lightTypeParametric, lightTypeFreeform, lightTypeSprite, lightTypePoint, lightTypeGlobal }; - - public static GUIContent generalLightType = EditorGUIUtility.TrTextContent("Light Type", "Specify the light type"); - public static GUIContent generalFalloffSize = EditorGUIUtility.TrTextContent("Falloff", "Specify the falloff of the light"); - public static GUIContent generalFalloffIntensity = EditorGUIUtility.TrTextContent("Falloff Intensity", "Adjusts the falloff curve"); - public static GUIContent generalLightColor = EditorGUIUtility.TrTextContent("Color", "Specify the light color"); - public static GUIContent generalLightIntensity = EditorGUIUtility.TrTextContent("Intensity", "Specify the light color's intensity"); - public static GUIContent generalUseNormalMap = EditorGUIUtility.TrTextContent("Use Normal Map", "Specify whether the light considers normal maps"); - public static GUIContent generalVolumeOpacity = EditorGUIUtility.TrTextContent("Volume Opacity", "Specify the light's volumetric light volume opacity"); - public static GUIContent generalBlendStyle = EditorGUIUtility.TrTextContent("Blend Style", "Specify the blend style"); - public static GUIContent generalLightOverlapMode = EditorGUIUtility.TrTextContent("Alpha Blend on Overlap", "Use alpha blending instead of additive blending when this light overlaps others"); - public static GUIContent generalLightOrder = EditorGUIUtility.TrTextContent("Light Order", "The relative order in which lights of the same blend style get rendered."); - public static GUIContent generalShadowIntensity = EditorGUIUtility.TrTextContent("Shadow Intensity", "Controls the shadow's darkness."); - public static GUIContent generalShadowVolumeIntensity = EditorGUIUtility.TrTextContent("Shadow Volume Intensity", "Controls the shadow volume's darkness."); - public static GUIContent generalSortingLayerPrefixLabel = EditorGUIUtility.TrTextContent("Target Sorting Layers", "Apply this light to the specified sorting layers."); - public static GUIContent generalLightNoLightEnabled = EditorGUIUtility.TrTextContentWithIcon("No valid blend styles are enabled.", MessageType.Error); - - public static GUIContent pointLightQuality = EditorGUIUtility.TrTextContent("Quality", "Use accurate if there are noticeable visual issues"); - public static GUIContent pointLightInnerAngle = EditorGUIUtility.TrTextContent("Inner Angle", "Specify the inner angle of the light"); - public static GUIContent pointLightOuterAngle = EditorGUIUtility.TrTextContent("Outer Angle", "Specify the outer angle of the light"); - public static GUIContent pointLightInnerRadius = EditorGUIUtility.TrTextContent("Inner Radius", "Specify the inner radius of the light"); - public static GUIContent pointLightOuterRadius = EditorGUIUtility.TrTextContent("Outer Radius", "Specify the outer radius of the light"); - public static GUIContent pointLightZDistance = EditorGUIUtility.TrTextContent("Distance", "Specify the Z Distance of the light"); - public static GUIContent pointLightCookie = EditorGUIUtility.TrTextContent("Cookie", "Specify a sprite as the cookie for the light"); - - - public static GUIContent shapeLightSprite = EditorGUIUtility.TrTextContent("Sprite", "Specify the sprite"); - public static GUIContent shapeLightParametricRadius = EditorGUIUtility.TrTextContent("Radius", "Adjust the size of the object"); - public static GUIContent shapeLightParametricSides = EditorGUIUtility.TrTextContent("Sides", "Adjust the shapes number of sides"); - public static GUIContent shapeLightFalloffOffset = EditorGUIUtility.TrTextContent("Falloff Offset", "Specify the shape's falloff offset"); - public static GUIContent shapeLightAngleOffset = EditorGUIUtility.TrTextContent("Angle Offset", "Adjust the rotation of the object"); - - public static GUIContent renderPipelineUnassignedWarning = EditorGUIUtility.TrTextContentWithIcon("Universal scriptable renderpipeline asset must be assigned in Graphics Settings or Quality Settings.", MessageType.Warning); - public static GUIContent asset2DUnassignedWarning = EditorGUIUtility.TrTextContentWithIcon("2D renderer data must be assigned to your universal render pipeline asset or camera.", MessageType.Warning); - } - - const float k_GlobalLightGizmoSize = 1.2f; - const float k_AngleCapSize = 0.16f * k_GlobalLightGizmoSize; - const float k_AngleCapOffset = 0.08f * k_GlobalLightGizmoSize; - const float k_AngleCapOffsetSecondary = -0.05f; - const float k_RangeCapSize = 0.025f * k_GlobalLightGizmoSize; - const float k_InnerRangeCapSize = 0.08f * k_GlobalLightGizmoSize; - - SerializedProperty m_LightType; - SerializedProperty m_LightColor; - SerializedProperty m_LightIntensity; - SerializedProperty m_UseNormalMap; - SerializedProperty m_ShadowIntensity; - SerializedProperty m_ShadowVolumeIntensity; - SerializedProperty m_ApplyToSortingLayers; - SerializedProperty m_VolumetricAlpha; - SerializedProperty m_BlendStyleIndex; - SerializedProperty m_FalloffIntensity; - SerializedProperty m_PointZDistance; - SerializedProperty m_LightOrder; - SerializedProperty m_AlphaBlendOnOverlap; - - // Point Light Properties - SerializedProperty m_PointInnerAngle; - SerializedProperty m_PointOuterAngle; - SerializedProperty m_PointInnerRadius; - SerializedProperty m_PointOuterRadius; - SerializedProperty m_PointLightCookie; - SerializedProperty m_PointLightQuality; - - // Shape Light Properties - SerializedProperty m_ShapeLightParametricRadius; - SerializedProperty m_ShapeLightFalloffSize; - SerializedProperty m_ShapeLightParametricSides; - SerializedProperty m_ShapeLightParametricAngleOffset; - SerializedProperty m_ShapeLightFalloffOffset; - SerializedProperty m_ShapeLightSprite; - - int[] m_BlendStyleIndices; - GUIContent[] m_BlendStyleNames; - bool m_AnyBlendStyleEnabled = false; - - SortingLayerDropDown m_SortingLayerDropDown; - - Light2D lightObject => target as Light2D; - - Analytics.Renderer2DAnalytics m_Analytics; - HashSet m_ModifiedLights; - - private void AnalyticsTrackChanges(SerializedObject serializedObject) - { - if (serializedObject.hasModifiedProperties) - { - foreach (Object targetObj in serializedObject.targetObjects) - { - Light2D light2d = (Light2D)targetObj; - if(!m_ModifiedLights.Contains(light2d)) - m_ModifiedLights.Add(light2d); - } - } - } - - void OnEnable() - { - m_Analytics = Analytics.Renderer2DAnalytics.instance; - m_ModifiedLights = new HashSet(); - m_SortingLayerDropDown = new SortingLayerDropDown(); - - m_LightType = serializedObject.FindProperty("m_LightType"); - m_LightColor = serializedObject.FindProperty("m_Color"); - m_LightIntensity = serializedObject.FindProperty("m_Intensity"); - m_UseNormalMap = serializedObject.FindProperty("m_UseNormalMap"); - m_ShadowIntensity = serializedObject.FindProperty("m_ShadowIntensity"); - m_ShadowVolumeIntensity = serializedObject.FindProperty("m_ShadowVolumeIntensity"); - m_ApplyToSortingLayers = serializedObject.FindProperty("m_ApplyToSortingLayers"); - m_VolumetricAlpha = serializedObject.FindProperty("m_LightVolumeOpacity"); - m_BlendStyleIndex = serializedObject.FindProperty("m_BlendStyleIndex"); - m_FalloffIntensity = serializedObject.FindProperty("m_FalloffIntensity"); - m_PointZDistance = serializedObject.FindProperty("m_PointLightDistance"); - m_LightOrder = serializedObject.FindProperty("m_LightOrder"); - m_AlphaBlendOnOverlap = serializedObject.FindProperty("m_AlphaBlendOnOverlap"); - - // Point Light - m_PointInnerAngle = serializedObject.FindProperty("m_PointLightInnerAngle"); - m_PointOuterAngle = serializedObject.FindProperty("m_PointLightOuterAngle"); - m_PointInnerRadius = serializedObject.FindProperty("m_PointLightInnerRadius"); - m_PointOuterRadius = serializedObject.FindProperty("m_PointLightOuterRadius"); - m_PointLightCookie = serializedObject.FindProperty("m_LightCookieSprite"); - m_PointLightQuality = serializedObject.FindProperty("m_PointLightQuality"); - - // Shape Light - m_ShapeLightParametricRadius = serializedObject.FindProperty("m_ShapeLightParametricRadius"); - m_ShapeLightFalloffSize = serializedObject.FindProperty("m_ShapeLightFalloffSize"); - m_ShapeLightParametricSides = serializedObject.FindProperty("m_ShapeLightParametricSides"); - m_ShapeLightParametricAngleOffset = serializedObject.FindProperty("m_ShapeLightParametricAngleOffset"); - m_ShapeLightFalloffOffset = serializedObject.FindProperty("m_ShapeLightFalloffOffset"); - m_ShapeLightSprite = serializedObject.FindProperty("m_LightCookieSprite"); - - m_AnyBlendStyleEnabled = false; - var blendStyleIndices = new List(); - var blendStyleNames = new List(); - - var rendererData = Light2DEditorUtility.GetRenderer2DData(); - if (rendererData != null) - { - for (int i = 0; i < rendererData.lightBlendStyles.Length; ++i) - { - blendStyleIndices.Add(i); - - ref var blendStyle = ref rendererData.lightBlendStyles[i]; - blendStyleNames.Add(blendStyle.name); - m_AnyBlendStyleEnabled = true; - } - } - else - { - for (int i = 0; i < 4; ++i) - { - blendStyleIndices.Add(i); - blendStyleNames.Add("Operation" + i); - } - } - - m_BlendStyleIndices = blendStyleIndices.ToArray(); - m_BlendStyleNames = blendStyleNames.Select(x => new GUIContent(x)).ToArray(); - - - m_SortingLayerDropDown.OnEnable(serializedObject, "m_ApplyToSortingLayers"); - } - - internal void SendModifiedAnalytics(Analytics.Renderer2DAnalytics analytics, Light2D light) - { - Analytics.Light2DData lightData = new Analytics.Light2DData(); - lightData.was_create_event = false; - lightData.instance_id = light.GetInstanceID(); - lightData.light_type = light.lightType; - Analytics.Renderer2DAnalytics.instance.SendData(Analytics.AnalyticsDataTypes.k_LightDataString, lightData); - } - - void OnDestroy() - { - if(m_ModifiedLights != null && m_ModifiedLights.Count > 0) - { - foreach (Light2D light in m_ModifiedLights) - { - SendModifiedAnalytics(m_Analytics, light); - } - } - } - - void OnPointLight(SerializedObject serializedObject) - { - EditorGUI.BeginChangeCheck(); - EditorGUILayout.Slider(m_PointInnerAngle, 0, 360, Styles.pointLightInnerAngle); - if (EditorGUI.EndChangeCheck()) - m_PointInnerAngle.floatValue = Mathf.Min(m_PointInnerAngle.floatValue, m_PointOuterAngle.floatValue); - - EditorGUI.BeginChangeCheck(); - EditorGUILayout.Slider(m_PointOuterAngle, 0, 360, Styles.pointLightOuterAngle); - if (EditorGUI.EndChangeCheck()) - m_PointOuterAngle.floatValue = Mathf.Max(m_PointInnerAngle.floatValue, m_PointOuterAngle.floatValue); - - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(m_PointInnerRadius, Styles.pointLightInnerRadius); - if (EditorGUI.EndChangeCheck()) - m_PointInnerRadius.floatValue = Mathf.Max(0.0f, Mathf.Min(m_PointInnerRadius.floatValue, m_PointOuterRadius.floatValue)); - - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(m_PointOuterRadius, Styles.pointLightOuterRadius); - if (EditorGUI.EndChangeCheck()) - m_PointOuterRadius.floatValue = Mathf.Max(m_PointInnerRadius.floatValue, m_PointOuterRadius.floatValue); - - EditorGUILayout.Slider(m_FalloffIntensity, 0, 1, Styles.generalFalloffIntensity); - EditorGUILayout.PropertyField(m_PointLightCookie, Styles.pointLightCookie); - } - - void OnShapeLight(Light2D.LightType lightType, SerializedObject serializedObject) - { - if (lightType == Light2D.LightType.Sprite) - { - EditorGUILayout.PropertyField(m_ShapeLightSprite, Styles.shapeLightSprite); - } - else if (lightType == Light2D.LightType.Parametric || lightType == Light2D.LightType.Freeform) - { - if (lightType == Light2D.LightType.Parametric) - { - EditorGUILayout.PropertyField(m_ShapeLightParametricRadius, Styles.shapeLightParametricRadius); - if (m_ShapeLightParametricRadius.floatValue < 0) - m_ShapeLightParametricRadius.floatValue = 0; - - EditorGUILayout.IntSlider(m_ShapeLightParametricSides, 3, 48, Styles.shapeLightParametricSides); - EditorGUILayout.Slider(m_ShapeLightParametricAngleOffset, 0, 359, Styles.shapeLightAngleOffset); - } - - EditorGUILayout.PropertyField(m_ShapeLightFalloffSize, Styles.generalFalloffSize); - if (m_ShapeLightFalloffSize.floatValue < 0) - m_ShapeLightFalloffSize.floatValue = 0; - - EditorGUILayout.Slider(m_FalloffIntensity, 0, 1, Styles.generalFalloffIntensity); - - if (lightType == Light2D.LightType.Parametric || lightType == Light2D.LightType.Freeform) - { - bool oldWideMode = EditorGUIUtility.wideMode; - EditorGUIUtility.wideMode = true; - EditorGUILayout.PropertyField(m_ShapeLightFalloffOffset, Styles.shapeLightFalloffOffset); - EditorGUIUtility.wideMode = oldWideMode; - } - } - } - - Vector3 DrawAngleSlider2D(Transform transform, Quaternion rotation, float radius, float offset, Handles.CapFunction capFunc, float capSize, bool leftAngle, bool drawLine, bool useCapOffset, ref float angle) - { - float oldAngle = angle; - - float angleBy2 = (angle / 2) * (leftAngle ? -1.0f : 1.0f); - Vector3 trcwPos = Quaternion.AngleAxis(angleBy2, -transform.forward) * (transform.up); - Vector3 cwPos = transform.position + trcwPos * (radius + offset); - - float direction = leftAngle ? 1 : -1; - - // Offset the handle - float size = .25f * capSize; - - Vector3 handleOffset = useCapOffset ? rotation * new Vector3(direction * size, 0, 0) : Vector3.zero; - - EditorGUI.BeginChangeCheck(); - var id = GUIUtility.GetControlID("AngleSlider".GetHashCode(), FocusType.Passive); - Vector3 cwHandle = Handles.Slider2D(id, cwPos, handleOffset, Vector3.forward, rotation * Vector3.up, rotation * Vector3.right, capSize, capFunc, Vector3.zero); - if (EditorGUI.EndChangeCheck()) - { - Vector3 toCwHandle = (transform.position - cwHandle).normalized; - - angle = 360 - 2 * Quaternion.Angle(Quaternion.FromToRotation(transform.up, toCwHandle), Quaternion.identity); - angle = Mathf.Round(angle * 100) / 100f; - - float side = Vector3.Dot(direction * transform.right, toCwHandle); - if (side < 0) - { - if (oldAngle < 180) - angle = 0; - else - angle = 360; - } - } - - if (drawLine) - Handles.DrawLine(transform.position, cwHandle); - - return cwHandle; - } - - private float DrawAngleHandle(Transform transform, float radius, float offset, Handles.CapFunction capLeft, Handles.CapFunction capRight, ref float angle) - { - float old = angle; - float handleOffset = HandleUtility.GetHandleSize(transform.position) * offset; - float handleSize = HandleUtility.GetHandleSize(transform.position) * k_AngleCapSize; - - Quaternion rotLt = Quaternion.AngleAxis(-angle / 2, -transform.forward) * transform.rotation; - DrawAngleSlider2D(transform, rotLt, radius, handleOffset, capLeft, handleSize, true, true, true, ref angle); - - Quaternion rotRt = Quaternion.AngleAxis(angle / 2, -transform.forward) * transform.rotation; - DrawAngleSlider2D(transform, rotRt, radius, handleOffset, capRight, handleSize, false, true, true, ref angle); - - return angle - old; - } - - private void DrawRadiusArc(Transform transform, float radius, float angle, int steps, Handles.CapFunction capFunc, float capSize, bool even) - { - Handles.DrawWireArc(transform.position, transform.forward, Quaternion.AngleAxis(180 - angle / 2, transform.forward) * -transform.up, angle, radius); - } - - Handles.CapFunction GetCapFunc(Texture texture, bool isAngleHandle) - { - return (controlID, position, rotation, size, eventType) => Light2DEditorUtility.GUITextureCap(controlID, texture, position, rotation, size, eventType, isAngleHandle); - } - - private void DrawAngleHandles(Light2D light) - { - var oldColor = Handles.color; - Handles.color = Color.yellow; - - float outerAngle = light.pointLightOuterAngle; - float diff = DrawAngleHandle(light.transform, light.pointLightOuterRadius, k_AngleCapOffset, GetCapFunc(Styles.lightCapTopRight, true), GetCapFunc(Styles.lightCapBottomRight, true), ref outerAngle); - light.pointLightOuterAngle = outerAngle; - - if (diff != 0.0f) - light.pointLightInnerAngle = Mathf.Max(0.0f, light.pointLightInnerAngle + diff); - - float innerAngle = light.pointLightInnerAngle; - diff = DrawAngleHandle(light.transform, light.pointLightOuterRadius, -k_AngleCapOffset, GetCapFunc(Styles.lightCapTopLeft, true), GetCapFunc(Styles.lightCapBottomLeft, true), ref innerAngle); - light.pointLightInnerAngle = innerAngle; - - if (diff != 0.0f) - light.pointLightInnerAngle = light.pointLightInnerAngle < light.pointLightOuterAngle ? light.pointLightInnerAngle : light.pointLightOuterAngle; - - light.pointLightInnerAngle = Mathf.Min(light.pointLightInnerAngle, light.pointLightOuterAngle); - - Handles.color = oldColor; - } - - private void DrawRangeHandles(Light2D light) - { - var dummy = 0.0f; - bool radiusChanged = false; - Vector3 handlePos = Vector3.zero; - Quaternion rotLeft = Quaternion.AngleAxis(0, -light.transform.forward) * light.transform.rotation; - float handleOffset = HandleUtility.GetHandleSize(light.transform.position) * k_AngleCapOffsetSecondary; - float handleSize = HandleUtility.GetHandleSize(light.transform.position) * k_AngleCapSize; - - var oldColor = Handles.color; - Handles.color = Color.yellow; - - float outerRadius = light.pointLightOuterRadius; - EditorGUI.BeginChangeCheck(); - Vector3 returnPos = DrawAngleSlider2D(light.transform, rotLeft, outerRadius, -handleOffset, GetCapFunc(Styles.lightCapUp, false), handleSize, false, false, false, ref dummy); - if (EditorGUI.EndChangeCheck()) - { - var vec = (returnPos - light.transform.position).normalized; - light.transform.up = new Vector3(vec.x, vec.y, 0); - outerRadius = (returnPos - light.transform.position).magnitude; - outerRadius = outerRadius + handleOffset; - radiusChanged = true; - } - DrawRadiusArc(light.transform, light.pointLightOuterRadius, light.pointLightOuterAngle, 0, Handles.DotHandleCap, k_RangeCapSize, false); - - Handles.color = Color.gray; - float innerRadius = light.pointLightInnerRadius; - EditorGUI.BeginChangeCheck(); - returnPos = DrawAngleSlider2D(light.transform, rotLeft, innerRadius, handleOffset, GetCapFunc(Styles.lightCapDown, false), handleSize, true, false, false, ref dummy); - if (EditorGUI.EndChangeCheck()) - { - innerRadius = (returnPos - light.transform.position).magnitude; - innerRadius = innerRadius - handleOffset; - radiusChanged = true; - } - DrawRadiusArc(light.transform, light.pointLightInnerRadius, light.pointLightOuterAngle, 0, Handles.SphereHandleCap, k_InnerRangeCapSize, false); - - Handles.color = oldColor; - - if (radiusChanged) - { - light.pointLightInnerRadius = (outerRadius < innerRadius) ? outerRadius : innerRadius; - light.pointLightOuterRadius = (innerRadius > outerRadius) ? innerRadius : outerRadius; - } - } - - void OnSceneGUI() - { - var light = target as Light2D; - if (light == null) - return; - - Transform t = light.transform; - switch (light.lightType) - { - case Light2D.LightType.Point: - { - Undo.RecordObject(light.transform, "Edit Point Light Transform"); - Undo.RecordObject(light, "Edit Point Light"); - - DrawRangeHandles(light); - DrawAngleHandles(light); - - if (GUI.changed) - EditorUtility.SetDirty(light); - } - break; - case Light2D.LightType.Sprite: - { - var cookieSprite = light.lightCookieSprite; - if (cookieSprite != null) - { - Vector3 min = cookieSprite.bounds.min; - Vector3 max = cookieSprite.bounds.max; - - Vector3 v0 = t.TransformPoint(new Vector3(min.x, min.y)); - Vector3 v1 = t.TransformPoint(new Vector3(max.x, min.y)); - Vector3 v2 = t.TransformPoint(new Vector3(max.x, max.y)); - Vector3 v3 = t.TransformPoint(new Vector3(min.x, max.y)); - - Handles.DrawLine(v0, v1); - Handles.DrawLine(v1, v2); - Handles.DrawLine(v2, v3); - Handles.DrawLine(v3, v0); - } - } - break; - case Light2D.LightType.Parametric: - { - float radius = light.shapeLightParametricRadius; - float sides = light.shapeLightParametricSides; - float angleOffset = Mathf.PI / 2.0f + Mathf.Deg2Rad * light.shapeLightParametricAngleOffset; - - if (sides < 3) - sides = 3; - - if (sides == 4) - angleOffset = Mathf.PI / 4.0f + Mathf.Deg2Rad * light.shapeLightParametricAngleOffset; - - Vector3 direction = new Vector3(Mathf.Cos(angleOffset), Mathf.Sin(angleOffset), 0); - Vector3 startPoint = radius * direction; - Vector3 featherStartPoint = startPoint + light.shapeLightFalloffSize * direction; - float radiansPerSide = 2 * Mathf.PI / sides; - Vector3 falloffOffset = light.shapeLightFalloffOffset; - - for (int i = 0; i < sides; ++i) - { - float endAngle = (i + 1) * radiansPerSide; - - direction = new Vector3(Mathf.Cos(endAngle + angleOffset), Mathf.Sin(endAngle + angleOffset), 0); - Vector3 endPoint = radius * direction; - Vector3 featherEndPoint = endPoint + light.shapeLightFalloffSize * direction; - - Handles.DrawLine(t.TransformPoint(startPoint), t.TransformPoint(endPoint)); - Handles.DrawLine(t.TransformPoint(featherStartPoint + falloffOffset), t.TransformPoint(featherEndPoint + falloffOffset)); - - startPoint = endPoint; - featherStartPoint = featherEndPoint; - } - } - break; - case Light2D.LightType.Freeform: - { - // Draw the falloff shape's outline - List falloffShape = light.GetFalloffShape(); - Handles.color = Color.white; - - - Vector3 falloffOffset = m_ShapeLightFalloffOffset.vector2Value; - - for (int i = 0; i < falloffShape.Count - 1; ++i) - { - Handles.DrawLine(t.TransformPoint(falloffShape[i]) + falloffOffset, t.TransformPoint(falloffShape[i + 1]) + falloffOffset); - Handles.DrawLine(t.TransformPoint(light.shapePath[i]), t.TransformPoint(light.shapePath[i + 1])); - } - - Handles.DrawLine(t.TransformPoint(falloffShape[falloffShape.Count - 1]) + falloffOffset, t.TransformPoint(falloffShape[0]) + falloffOffset); - Handles.DrawLine(t.TransformPoint(light.shapePath[falloffShape.Count - 1]), t.TransformPoint(light.shapePath[0])); - } - break; - } - } - - public override void OnInspectorGUI() - { - UniversalRenderPipelineAsset asset = UniversalRenderPipeline.asset; - - if (asset != null) - { - if (!Light2DEditorUtility.IsUsing2DRenderer()) - { - EditorGUILayout.HelpBox(Styles.asset2DUnassignedWarning); - return; - } - } - else - { - EditorGUILayout.HelpBox(Styles.renderPipelineUnassignedWarning); - return; - } - - EditorGUILayout.Space(); - - serializedObject.Update(); - - var meshChanged = false; - Rect lightTypeRect = EditorGUILayout.GetControlRect(); - EditorGUI.BeginProperty(lightTypeRect, GUIContent.none, m_LightType); - EditorGUI.BeginChangeCheck(); - int newLightType = EditorGUI.Popup(lightTypeRect, Styles.generalLightType, m_LightType.intValue, Styles.lightTypeOptions); - if (EditorGUI.EndChangeCheck()) - { - m_LightType.intValue = newLightType; - meshChanged = true; - } - EditorGUI.EndProperty(); - - switch (m_LightType.intValue) - { - case (int)Light2D.LightType.Point: - { - OnPointLight(serializedObject); - } - break; - case (int)Light2D.LightType.Parametric: - case (int)Light2D.LightType.Freeform: - case (int)Light2D.LightType.Sprite: - { - OnShapeLight((Light2D.LightType)m_LightType.intValue, serializedObject); - } - break; - } - - if(m_LightType.intValue != (int)Light2D.LightType.Global) - EditorGUILayout.PropertyField(m_AlphaBlendOnOverlap, Styles.generalLightOverlapMode); - - EditorGUILayout.PropertyField(m_LightOrder, Styles.generalLightOrder); - - if (!m_AnyBlendStyleEnabled) - EditorGUILayout.HelpBox(Styles.generalLightNoLightEnabled); - else - EditorGUILayout.IntPopup(m_BlendStyleIndex, m_BlendStyleNames, m_BlendStyleIndices, Styles.generalBlendStyle); - - EditorGUILayout.PropertyField(m_LightColor, Styles.generalLightColor); - - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(m_LightIntensity, Styles.generalLightIntensity); - if (EditorGUI.EndChangeCheck()) - m_LightIntensity.floatValue = Mathf.Max(m_LightIntensity.floatValue, 0); - - if (m_LightType.intValue != (int)Light2D.LightType.Global) - { - - EditorGUILayout.PropertyField(m_UseNormalMap, Styles.generalUseNormalMap); - - if (m_UseNormalMap.boolValue) - { - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(m_PointZDistance, Styles.pointLightZDistance); - if (EditorGUI.EndChangeCheck()) - m_PointZDistance.floatValue = Mathf.Max(0.0f, m_PointZDistance.floatValue); - EditorGUILayout.PropertyField(m_PointLightQuality, Styles.pointLightQuality); - } - - EditorGUILayout.Slider(m_VolumetricAlpha, 0, 1, Styles.generalVolumeOpacity); - - EditorGUILayout.Slider(m_ShadowIntensity, 0, 1, Styles.generalShadowIntensity); - if(m_VolumetricAlpha.floatValue > 0) - EditorGUILayout.Slider(m_ShadowVolumeIntensity, 0, 1, Styles.generalShadowVolumeIntensity); - } - - m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.generalSortingLayerPrefixLabel, AnalyticsTrackChanges); - - if (m_LightType.intValue == (int)Light2D.LightType.Freeform) - { - DoEditButton(PathEditorToolContents.icon, "Edit Shape"); - DoPathInspector(); - DoSnappingInspector(); - } - - AnalyticsTrackChanges(serializedObject); - if (serializedObject.ApplyModifiedProperties()) - { - if(meshChanged) - lightObject.UpdateMesh(); - } - } - - } -} +using System.Collections.Generic; +using System.Linq; +using UnityEditor.EditorTools; +using UnityEditor.Rendering.Universal.Path2D; +using UnityEngine; +using UnityEngine.Rendering.Universal; + + +namespace UnityEditor.Rendering.Universal +{ + [CustomEditor(typeof(Light2D))] + [CanEditMultipleObjects] + internal class Light2DEditor : PathComponentEditor + { + [EditorTool("Edit Freeform Shape", typeof(Light2D))] + class FreeformShapeTool : PathEditorTool + { + const string k_ShapePath = "m_ShapePath"; + + public override bool IsAvailable() + { + var light = target as Light2D; + + if (light == null) + return false; + else + return base.IsAvailable() && light.lightType == Light2D.LightType.Freeform; + } + + protected override IShape GetShape(Object target) + { + return (target as Light2D).shapePath.ToPolygon(false); + } + + protected override void SetShape(ScriptablePath shapeEditor, SerializedObject serializedObject) + { + serializedObject.Update(); + + var pointsProperty = serializedObject.FindProperty(k_ShapePath); + pointsProperty.arraySize = shapeEditor.pointCount; + + for (var i = 0; i < shapeEditor.pointCount; ++i) + pointsProperty.GetArrayElementAtIndex(i).vector3Value = shapeEditor.GetPoint(i).position; + + ((Light2D)(serializedObject.targetObject)).UpdateMesh(true); + + // This is untracked right now... + serializedObject.ApplyModifiedProperties(); + } + } + + private static class Styles + { + public static readonly GUIContent InnerOuterSpotAngle = EditorGUIUtility.TrTextContent("Inner / Outer Spot Angle", "Adjusts the inner / outer angles of this light to change the angle ranges of this Spot Light’s beam."); + + public static Texture lightCapTopRight = Resources.Load("LightCapTopRight"); + public static Texture lightCapTopLeft = Resources.Load("LightCapTopLeft"); + public static Texture lightCapBottomLeft = Resources.Load("LightCapBottomLeft"); + public static Texture lightCapBottomRight = Resources.Load("LightCapBottomRight"); + public static Texture lightCapUp = Resources.Load("LightCapUp"); + public static Texture lightCapDown = Resources.Load("LightCapDown"); + + + public static GUIContent lightTypeFreeform = new GUIContent("Freeform", Resources.Load("InspectorIcons/FreeformLight") as Texture); + public static GUIContent lightTypeSprite = new GUIContent("Sprite", Resources.Load("InspectorIcons/SpriteLight") as Texture); + public static GUIContent lightTypePoint = new GUIContent("Spot", Resources.Load("InspectorIcons/PointLight") as Texture); + public static GUIContent lightTypeGlobal = new GUIContent("Global", Resources.Load("InspectorIcons/GlobalLight") as Texture); + public static GUIContent[] lightTypeOptions = new GUIContent[] { lightTypeFreeform, lightTypeSprite, lightTypePoint, lightTypeGlobal }; + + + public static GUIContent blendingSettingsFoldout = EditorGUIUtility.TrTextContent("Blending", "Options used for blending"); + public static GUIContent shadowsSettingsFoldout = EditorGUIUtility.TrTextContent("Shadows", "Options used for shadows"); + public static GUIContent volumetricSettingsFoldout = EditorGUIUtility.TrTextContent("Volumetric", "Options used for volumetric lighting"); + public static GUIContent normalMapsSettingsFoldout = EditorGUIUtility.TrTextContent("Normal Maps", "Options used for normal maps"); + + public static GUIContent generalLightType = EditorGUIUtility.TrTextContent("Light Type", "Select the light type. \n\nGlobal Light: For ambient light. \nSpot Light: For a spot light / point light. \nFreeform Light: For a custom shape light. \nSprite Light: For a custom light cookie using Sprites."); + + public static GUIContent generalFalloffSize = EditorGUIUtility.TrTextContent("Falloff", "Adjusts the falloff area of this light. The higher the falloff value, the larger area the falloff spans."); + public static GUIContent generalFalloffIntensity = EditorGUIUtility.TrTextContent("Falloff Strength", "Adjusts the falloff curve to control the softness of this light’s edges. The higher the falloff strength, the softer the edges of this light."); + public static GUIContent generalLightColor = EditorGUIUtility.TrTextContent("Color", "Adjusts this light’s color."); + public static GUIContent generalLightIntensity = EditorGUIUtility.TrTextContent("Intensity", "Adjusts this light’s color intensity by using multiply to brighten the Sprite beyond its original color."); + public static GUIContent generalVolumeIntensity = EditorGUIUtility.TrTextContent("Intensity", "Adjusts the intensity of this additional light volume that's additively blended on top of this light. To enable the Volumetric Shadow Strength, increase this Intensity to be greater than 0."); + public static GUIContent generalBlendStyle = EditorGUIUtility.TrTextContent("Blend Style", "Adjusts how this light blends with the Sprites on the Target Sorting Layers. Different Blend Styles can be customized in the 2D Renderer Data Asset."); + public static GUIContent generalLightOverlapOperation = EditorGUIUtility.TrTextContent("Overlap Operation", "Determines how this light blends with the other lights either through additive or alpha blending."); + public static GUIContent generalLightOrder = EditorGUIUtility.TrTextContent("Light Order", "Determines the relative order in which lights of the same Blend Style get rendered. Lights with lower values are rendered first."); + public static GUIContent generalShadowIntensity = EditorGUIUtility.TrTextContent("Strength", "Adjusts the amount of light occlusion from the Shadow Caster 2D component(s) when blocking this light.The higher the value, the more opaque the shadow becomes."); + public static GUIContent generalShadowVolumeIntensity = EditorGUIUtility.TrTextContent("Shadow Strength", "Adjusts the amount of volume light occlusion from the Shadow Caster 2D component(s) when blocking this light."); + public static GUIContent generalSortingLayerPrefixLabel = EditorGUIUtility.TrTextContent("Target Sorting Layers", "Determines which layers this light affects. To optimize performance, minimize the number of layers this light affects."); + public static GUIContent generalLightNoLightEnabled = EditorGUIUtility.TrTextContentWithIcon("No valid blend styles are enabled.", MessageType.Error); + public static GUIContent generalNormalMapZDistance = EditorGUIUtility.TrTextContent("Distance", "Adjusts the z-axis distance of this light and the lit Sprite(s). Do note that this distance does not Transform the position of this light in the Scene."); + public static GUIContent generalNormalMapLightQuality = EditorGUIUtility.TrTextContent("Quality", "Determines the accuracy of the lighting calculations when normal map is used. To optimize for performance, select Fast."); + + public static GUIContent pointLightRadius = EditorGUIUtility.TrTextContent("Radius", "Adjusts the inner / outer radius of this light to change the size of this light."); + public static GUIContent pointLightInner = EditorGUIUtility.TrTextContent("Inner", "Specify the inner radius of the light"); + public static GUIContent pointLightOuter = EditorGUIUtility.TrTextContent("Outer", "Specify the outer radius of the light"); + public static GUIContent pointLightSprite = EditorGUIUtility.TrTextContent("Sprite", "Specify the sprite (deprecated)"); + + public static GUIContent shapeLightSprite = EditorGUIUtility.TrTextContent("Sprite", "Assign a Sprite which acts as a mask to create a light cookie."); + + public static GUIContent deprecatedParametricLightWarningSingle = EditorGUIUtility.TrTextContentWithIcon("Parametic Lights have been deprecated. To continue, upgrade your Parametric Light to a Freeform Light to enjoy similar light functionality.", MessageType.Warning); + public static GUIContent deprecatedParametricLightWarningMulti = EditorGUIUtility.TrTextContentWithIcon("Parametic Lights have been deprecated. To continue, upgrade your Parametric Lights to Freeform Lights to enjoy similar light functionality.", MessageType.Warning); + public static GUIContent deprecatedParametricLightInstructions = EditorGUIUtility.TrTextContent("Alternatively, you may choose to upgrade from the menu. Window > Rendering > Render Pipeline Converter > URP 2D Converters"); + public static GUIContent deprecatedParametricLightButtonSingle = EditorGUIUtility.TrTextContent("Upgrade Parametric Light"); + public static GUIContent deprecatedParametricLightButtonMulti = EditorGUIUtility.TrTextContent("Upgrade Parametric Lights"); + + public static GUIContent renderPipelineUnassignedWarning = EditorGUIUtility.TrTextContentWithIcon("Universal scriptable renderpipeline asset must be assigned in Graphics Settings or Quality Settings.", MessageType.Warning); + public static GUIContent asset2DUnassignedWarning = EditorGUIUtility.TrTextContentWithIcon("2D renderer data must be assigned to your universal render pipeline asset or camera.", MessageType.Warning); + + public static string deprecatedParametricLightDialogTextSingle = "The upgrade will convert the selected parametric light into a freeform light. You can't undo this operation."; + public static string deprecatedParametricLightDialogTextMulti = "The upgrade will convert the selected parametric lights into freeform lights. You can't undo this operation."; + public static string deprecatedParametricLightDialogTitle = "Parametric Light Upgrader"; + public static string deprecatedParametricLightDialogProceed = "Proceed"; + public static string deprecatedParametricLightDialogCancel = "Cancel"; + } + + const float k_GlobalLightGizmoSize = 1.2f; + const float k_AngleCapSize = 0.16f * k_GlobalLightGizmoSize; + const float k_AngleCapOffset = 0.08f * k_GlobalLightGizmoSize; + const float k_AngleCapOffsetSecondary = -0.05f; + const float k_RangeCapSize = 0.025f * k_GlobalLightGizmoSize; + const float k_InnerRangeCapSize = 0.08f * k_GlobalLightGizmoSize; + + SerializedProperty m_LightType; + SerializedProperty m_LightColor; + SerializedProperty m_LightIntensity; + SerializedProperty m_UseNormalMap; + SerializedProperty m_ShadowIntensity; + SerializedProperty m_ShadowIntensityEnabled; + SerializedProperty m_ShadowVolumeIntensity; + SerializedProperty m_ShadowVolumeIntensityEnabled; + SerializedProperty m_ApplyToSortingLayers; + SerializedProperty m_VolumetricIntensity; + SerializedProperty m_VolumetricIntensityEnabled; + SerializedProperty m_BlendStyleIndex; + SerializedProperty m_FalloffIntensity; + SerializedProperty m_NormalMapZDistance; + SerializedProperty m_NormalMapQuality; + SerializedProperty m_LightOrder; + SerializedProperty m_OverlapOperation; + + // Point Light Properties + SerializedProperty m_PointInnerAngle; + SerializedProperty m_PointOuterAngle; + SerializedProperty m_PointInnerRadius; + SerializedProperty m_PointOuterRadius; + SerializedProperty m_DeprecatedPointLightSprite; + + // Shape Light Properties + SerializedProperty m_ShapeLightParametricRadius; + SerializedProperty m_ShapeLightFalloffSize; + SerializedProperty m_ShapeLightParametricSides; + SerializedProperty m_ShapeLightSprite; + + SavedBool m_BlendingSettingsFoldout; + SavedBool m_ShadowsSettingsFoldout; + SavedBool m_VolumetricSettingsFoldout; + SavedBool m_NormalMapsSettingsFoldout; + + + int[] m_BlendStyleIndices; + GUIContent[] m_BlendStyleNames; + bool m_AnyBlendStyleEnabled = false; + + SortingLayerDropDown m_SortingLayerDropDown; + + Light2D lightObject => target as Light2D; + + Analytics.Renderer2DAnalytics m_Analytics; + HashSet m_ModifiedLights; + + private void AnalyticsTrackChanges(SerializedObject serializedObject) + { + if (serializedObject.hasModifiedProperties) + { + foreach (Object targetObj in serializedObject.targetObjects) + { + Light2D light2d = (Light2D)targetObj; + if (!m_ModifiedLights.Contains(light2d)) + m_ModifiedLights.Add(light2d); + } + } + } + + void OnEnable() + { + m_Analytics = Analytics.Renderer2DAnalytics.instance; + m_ModifiedLights = new HashSet(); + m_SortingLayerDropDown = new SortingLayerDropDown(); + + m_BlendingSettingsFoldout = new SavedBool($"{target.GetType()}.2DURPBlendingSettingsFoldout", false); + m_ShadowsSettingsFoldout = new SavedBool($"{target.GetType()}.2DURPShadowsSettingsFoldout", false); + m_VolumetricSettingsFoldout = new SavedBool($"{target.GetType()}.2DURPVolumetricSettingsFoldout", false); + m_NormalMapsSettingsFoldout = new SavedBool($"{target.GetType()}.2DURPNormalMapsSettingsFoldout", false); + + m_LightType = serializedObject.FindProperty("m_LightType"); + m_LightColor = serializedObject.FindProperty("m_Color"); + m_LightIntensity = serializedObject.FindProperty("m_Intensity"); + m_UseNormalMap = serializedObject.FindProperty("m_UseNormalMap"); + m_ShadowIntensity = serializedObject.FindProperty("m_ShadowIntensity"); + m_ShadowIntensityEnabled = serializedObject.FindProperty("m_ShadowIntensityEnabled"); + m_ShadowVolumeIntensity = serializedObject.FindProperty("m_ShadowVolumeIntensity"); + m_ShadowVolumeIntensityEnabled = serializedObject.FindProperty("m_ShadowVolumeIntensityEnabled"); + m_ApplyToSortingLayers = serializedObject.FindProperty("m_ApplyToSortingLayers"); + m_VolumetricIntensity = serializedObject.FindProperty("m_LightVolumeIntensity"); + m_VolumetricIntensityEnabled = serializedObject.FindProperty("m_LightVolumeIntensityEnabled"); + m_BlendStyleIndex = serializedObject.FindProperty("m_BlendStyleIndex"); + m_FalloffIntensity = serializedObject.FindProperty("m_FalloffIntensity"); + m_NormalMapZDistance = serializedObject.FindProperty("m_NormalMapDistance"); + m_NormalMapQuality = serializedObject.FindProperty("m_NormalMapQuality"); + m_LightOrder = serializedObject.FindProperty("m_LightOrder"); + m_OverlapOperation = serializedObject.FindProperty("m_OverlapOperation"); + + // Point Light + m_PointInnerAngle = serializedObject.FindProperty("m_PointLightInnerAngle"); + m_PointOuterAngle = serializedObject.FindProperty("m_PointLightOuterAngle"); + m_PointInnerRadius = serializedObject.FindProperty("m_PointLightInnerRadius"); + m_PointOuterRadius = serializedObject.FindProperty("m_PointLightOuterRadius"); + m_DeprecatedPointLightSprite = serializedObject.FindProperty("m_DeprecatedPointLightCookieSprite"); + + // Shape Light + m_ShapeLightParametricRadius = serializedObject.FindProperty("m_ShapeLightParametricRadius"); + m_ShapeLightFalloffSize = serializedObject.FindProperty("m_ShapeLightFalloffSize"); + m_ShapeLightParametricSides = serializedObject.FindProperty("m_ShapeLightParametricSides"); + m_ShapeLightSprite = serializedObject.FindProperty("m_LightCookieSprite"); + + m_AnyBlendStyleEnabled = false; + var blendStyleIndices = new List(); + var blendStyleNames = new List(); + + var rendererData = Light2DEditorUtility.GetRenderer2DData(); + if (rendererData != null) + { + for (int i = 0; i < rendererData.lightBlendStyles.Length; ++i) + { + blendStyleIndices.Add(i); + + ref var blendStyle = ref rendererData.lightBlendStyles[i]; + + if (blendStyle.maskTextureChannel == Light2DBlendStyle.TextureChannel.None) + blendStyleNames.Add(blendStyle.name); + else + { + var name = string.Format("{0} ({1})", blendStyle.name, blendStyle.maskTextureChannel); + blendStyleNames.Add(name); + } + + m_AnyBlendStyleEnabled = true; + } + } + else + { + for (int i = 0; i < 4; ++i) + { + blendStyleIndices.Add(i); + blendStyleNames.Add("Operation" + i); + } + } + + m_BlendStyleIndices = blendStyleIndices.ToArray(); + m_BlendStyleNames = blendStyleNames.Select(x => new GUIContent(x)).ToArray(); + + + m_SortingLayerDropDown.OnEnable(serializedObject, "m_ApplyToSortingLayers"); + } + + internal void SendModifiedAnalytics(Analytics.Renderer2DAnalytics analytics, Light2D light) + { + Analytics.Light2DData lightData = new Analytics.Light2DData(); + lightData.was_create_event = false; + lightData.instance_id = light.GetInstanceID(); + lightData.light_type = light.lightType; + Analytics.Renderer2DAnalytics.instance.SendData(Analytics.AnalyticsDataTypes.k_LightDataString, lightData); + } + + void OnDestroy() + { + if (m_ModifiedLights != null && m_ModifiedLights.Count > 0) + { + foreach (Light2D light in m_ModifiedLights) + { + SendModifiedAnalytics(m_Analytics, light); + } + } + } + + void DrawBlendingGroup() + { + CoreEditorUtils.DrawSplitter(false); + m_BlendingSettingsFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.blendingSettingsFoldout, m_BlendingSettingsFoldout.value); + if (m_BlendingSettingsFoldout.value) + { + if (!m_AnyBlendStyleEnabled) + EditorGUILayout.HelpBox(Styles.generalLightNoLightEnabled); + else + EditorGUILayout.IntPopup(m_BlendStyleIndex, m_BlendStyleNames, m_BlendStyleIndices, Styles.generalBlendStyle); + + EditorGUILayout.PropertyField(m_LightOrder, Styles.generalLightOrder); + EditorGUILayout.PropertyField(m_OverlapOperation, Styles.generalLightOverlapOperation); + } + } + + void DrawShadowsGroup() + { + CoreEditorUtils.DrawSplitter(false); + m_ShadowsSettingsFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.shadowsSettingsFoldout, m_ShadowsSettingsFoldout.value); + if (m_ShadowsSettingsFoldout.value) + { + DrawToggleProperty(Styles.generalShadowIntensity, m_ShadowIntensityEnabled, m_ShadowIntensity); + } + } + + void DrawVolumetricGroup() + { + CoreEditorUtils.DrawSplitter(false); + m_VolumetricSettingsFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.volumetricSettingsFoldout, m_VolumetricSettingsFoldout.value); + if (m_VolumetricSettingsFoldout.value) + { + DrawToggleProperty(Styles.generalVolumeIntensity, m_VolumetricIntensityEnabled, m_VolumetricIntensity); + if (m_VolumetricIntensity.floatValue < 0) + m_VolumetricIntensity.floatValue = 0; + + EditorGUI.BeginDisabledGroup(!m_VolumetricIntensityEnabled.boolValue); + DrawToggleProperty(Styles.generalShadowVolumeIntensity, m_ShadowVolumeIntensityEnabled, m_ShadowVolumeIntensity); + EditorGUI.EndDisabledGroup(); + } + } + + void DrawNormalMapGroup() + { + CoreEditorUtils.DrawSplitter(false); + m_NormalMapsSettingsFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.normalMapsSettingsFoldout, m_NormalMapsSettingsFoldout.value); + if (m_NormalMapsSettingsFoldout.value) + { + EditorGUILayout.PropertyField(m_NormalMapQuality, Styles.generalNormalMapLightQuality); + + EditorGUI.BeginDisabledGroup(m_NormalMapQuality.intValue == (int)Light2D.NormalMapQuality.Disabled); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_NormalMapZDistance, Styles.generalNormalMapZDistance); + if (EditorGUI.EndChangeCheck()) + m_NormalMapZDistance.floatValue = Mathf.Max(0.0f, m_NormalMapZDistance.floatValue); + + EditorGUI.EndDisabledGroup(); + } + } + + void DrawFoldouts() + { + DrawBlendingGroup(); + DrawShadowsGroup(); + DrawVolumetricGroup(); + DrawNormalMapGroup(); + } + + void DrawRadiusProperties(GUIContent label, SerializedProperty innerRadius, GUIContent content1, SerializedProperty outerRadius, GUIContent content2) + { + GUIStyle style = GUI.skin.box; + + float savedLabelWidth = EditorGUIUtility.labelWidth; + int savedIndentLevel = EditorGUI.indentLevel; + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel(label); + EditorGUILayout.BeginHorizontal(); + EditorGUI.indentLevel = 0; + EditorGUIUtility.labelWidth = style.CalcSize(content1).x; + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(innerRadius, content1); + if (EditorGUI.EndChangeCheck()) + { + if (innerRadius.floatValue > outerRadius.floatValue) + innerRadius.floatValue = outerRadius.floatValue; + else if (innerRadius.floatValue < 0) + innerRadius.floatValue = 0; + } + + EditorGUIUtility.labelWidth = style.CalcSize(content2).x; + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(outerRadius, content2); + if (EditorGUI.EndChangeCheck() && outerRadius.floatValue < innerRadius.floatValue) + outerRadius.floatValue = innerRadius.floatValue; + + EditorGUILayout.EndHorizontal(); + EditorGUILayout.EndHorizontal(); + EditorGUIUtility.labelWidth = savedLabelWidth; + EditorGUI.indentLevel = savedIndentLevel; + } + + void DrawToggleProperty(GUIContent label, SerializedProperty boolProperty, SerializedProperty property) + { + int savedIndentLevel = EditorGUI.indentLevel; + float savedLabelWidth = EditorGUIUtility.labelWidth; + const int kCheckboxWidth = 20; + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(boolProperty, GUIContent.none, GUILayout.MaxWidth(kCheckboxWidth)); + + EditorGUIUtility.labelWidth = EditorGUIUtility.labelWidth - kCheckboxWidth; + EditorGUI.BeginDisabledGroup(!boolProperty.boolValue); + EditorGUILayout.PropertyField(property, label); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.EndHorizontal(); + + EditorGUI.indentLevel = savedIndentLevel; + + EditorGUIUtility.labelWidth = savedLabelWidth; + } + + public void DrawInnerAndOuterSpotAngle(SerializedProperty minProperty, SerializedProperty maxProperty, GUIContent label) + { + float textFieldWidth = 45f; + + float min = minProperty.floatValue; + float max = maxProperty.floatValue; + + var rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + // This widget is a little bit of a special case. + // The right hand side of the min max slider will control the reset of the max value + // The left hand side of the min max slider will control the reset of the min value + // The label itself will not have a right click and reset value. + + rect = EditorGUI.PrefixLabel(rect, label); + EditorGUI.BeginProperty(new Rect(rect) { width = rect.width * 0.5f }, label, minProperty); + EditorGUI.BeginProperty(new Rect(rect) { xMin = rect.x + rect.width * 0.5f }, GUIContent.none, maxProperty); + + var minRect = new Rect(rect) { width = textFieldWidth }; + var maxRect = new Rect(rect) { xMin = rect.xMax - textFieldWidth }; + var sliderRect = new Rect(rect) { xMin = minRect.xMax + 4, xMax = maxRect.xMin - 4 }; + + EditorGUI.BeginChangeCheck(); + EditorGUI.DelayedFloatField(minRect, minProperty, GUIContent.none); + if (EditorGUI.EndChangeCheck()) + { + if (minProperty.floatValue > maxProperty.floatValue) + minProperty.floatValue = maxProperty.floatValue; + else if (minProperty.floatValue < 0) + minProperty.floatValue = 0; + } + + EditorGUI.BeginChangeCheck(); + EditorGUI.MinMaxSlider(sliderRect, ref min, ref max, 0f, 360f); + + if (EditorGUI.EndChangeCheck()) + { + minProperty.floatValue = min; + maxProperty.floatValue = max; + } + + EditorGUI.BeginChangeCheck(); + EditorGUI.DelayedFloatField(maxRect, m_PointOuterAngle, GUIContent.none); + if (EditorGUI.EndChangeCheck()) + { + if (minProperty.floatValue > maxProperty.floatValue) + maxProperty.floatValue = minProperty.floatValue; + else if (maxProperty.floatValue > 360) + maxProperty.floatValue = 360; + } + + + EditorGUI.EndProperty(); + EditorGUI.EndProperty(); + } + + void DrawGlobalLight(SerializedObject serializedObject) + { + m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.generalSortingLayerPrefixLabel, AnalyticsTrackChanges); + DrawBlendingGroup(); + } + + void DrawParametricDeprecated(SerializedObject serializedObject) + { + GUIContent buttonText = targets.Length > 1 ? Styles.deprecatedParametricLightButtonMulti : Styles.deprecatedParametricLightButtonSingle; + GUIContent helpText = targets.Length > 1 ? Styles.deprecatedParametricLightWarningMulti : Styles.deprecatedParametricLightWarningSingle; + string dialogText = targets.Length > 1 ? Styles.deprecatedParametricLightDialogTextMulti : Styles.deprecatedParametricLightDialogTextSingle; + + EditorGUILayout.HelpBox(helpText); + EditorGUILayout.Space(); + + + if (GUILayout.Button(buttonText)) + { + if (EditorUtility.DisplayDialog(Styles.deprecatedParametricLightDialogTitle, dialogText, Styles.deprecatedParametricLightDialogProceed, Styles.deprecatedParametricLightDialogCancel)) + { + for (int i = 0; i < targets.Length; i++) + { + Light2D light = (Light2D)targets[i]; + + if (light.lightType == (Light2D.LightType)Light2D.DeprecatedLightType.Parametric) + ParametricToFreeformLightUpgrader.UpgradeParametricLight(light); + } + } + } + EditorGUILayout.Space(); + EditorGUILayout.HelpBox(Styles.deprecatedParametricLightInstructions); + } + + bool DrawLightCommon() + { + var meshChanged = false; + Rect lightTypeRect = EditorGUILayout.GetControlRect(); + EditorGUI.BeginProperty(lightTypeRect, GUIContent.none, m_LightType); + EditorGUI.BeginChangeCheck(); + int newLightType = EditorGUI.Popup(lightTypeRect, Styles.generalLightType, m_LightType.intValue - 1, Styles.lightTypeOptions); // -1 is a bit hacky its to support compatibiltiy. We need something better. + if (EditorGUI.EndChangeCheck()) + { + m_LightType.intValue = newLightType + 1; // -1 is a bit hacky its to support compatibiltiy. We need something better. + meshChanged = true; + } + EditorGUI.EndProperty(); + + // Color and intensity + EditorGUILayout.PropertyField(m_LightColor, Styles.generalLightColor); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_LightIntensity, Styles.generalLightIntensity); + if (EditorGUI.EndChangeCheck()) + m_LightIntensity.floatValue = Mathf.Max(m_LightIntensity.floatValue, 0); + + return meshChanged; + } + + void DrawSpotLight(SerializedObject serializedObject) + { + DrawRadiusProperties(Styles.pointLightRadius, m_PointInnerRadius, Styles.pointLightInner, m_PointOuterRadius, Styles.pointLightOuter); + DrawInnerAndOuterSpotAngle(m_PointInnerAngle, m_PointOuterAngle, Styles.InnerOuterSpotAngle); + EditorGUILayout.Slider(m_FalloffIntensity, 0, 1, Styles.generalFalloffIntensity); + + if (m_DeprecatedPointLightSprite.objectReferenceValue != null) + EditorGUILayout.PropertyField(m_DeprecatedPointLightSprite, Styles.pointLightSprite); + + m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.generalSortingLayerPrefixLabel, AnalyticsTrackChanges); + + DrawFoldouts(); + } + + void DrawSpriteLight(SerializedObject serializedObject) + { + EditorGUILayout.PropertyField(m_ShapeLightSprite, Styles.shapeLightSprite); + + m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.generalSortingLayerPrefixLabel, AnalyticsTrackChanges); + DrawFoldouts(); + } + + void DrawShapeLight(SerializedObject serializedObject) + { + EditorGUILayout.PropertyField(m_ShapeLightFalloffSize, Styles.generalFalloffSize); + if (m_ShapeLightFalloffSize.floatValue < 0) + m_ShapeLightFalloffSize.floatValue = 0; + + EditorGUILayout.Slider(m_FalloffIntensity, 0, 1, Styles.generalFalloffIntensity); + + m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.generalSortingLayerPrefixLabel, AnalyticsTrackChanges); + + if (m_LightType.intValue == (int)Light2D.LightType.Freeform) + { + DoEditButton(PathEditorToolContents.icon, "Edit Shape"); + DoPathInspector(); + DoSnappingInspector(); + } + + DrawFoldouts(); + } + + Vector3 DrawAngleSlider2D(Transform transform, Quaternion rotation, float radius, float offset, Handles.CapFunction capFunc, float capSize, bool leftAngle, bool drawLine, bool useCapOffset, ref float angle) + { + float oldAngle = angle; + + float angleBy2 = (angle / 2) * (leftAngle ? -1.0f : 1.0f); + Vector3 trcwPos = Quaternion.AngleAxis(angleBy2, -transform.forward) * (transform.up); + Vector3 cwPos = transform.position + trcwPos * (radius + offset); + + float direction = leftAngle ? 1 : -1; + + // Offset the handle + float size = .25f * capSize; + + Vector3 handleOffset = useCapOffset ? rotation * new Vector3(direction * size, 0, 0) : Vector3.zero; + + EditorGUI.BeginChangeCheck(); + var id = GUIUtility.GetControlID("AngleSlider".GetHashCode(), FocusType.Passive); + Vector3 cwHandle = Handles.Slider2D(id, cwPos, handleOffset, Vector3.forward, rotation * Vector3.up, rotation * Vector3.right, capSize, capFunc, Vector3.zero); + if (EditorGUI.EndChangeCheck()) + { + Vector3 toCwHandle = (transform.position - cwHandle).normalized; + + angle = 360 - 2 * Quaternion.Angle(Quaternion.FromToRotation(transform.up, toCwHandle), Quaternion.identity); + angle = Mathf.Round(angle * 100) / 100f; + + float side = Vector3.Dot(direction * transform.right, toCwHandle); + if (side < 0) + { + if (oldAngle < 180) + angle = 0; + else + angle = 360; + } + } + + if (drawLine) + Handles.DrawLine(transform.position, cwHandle); + + return cwHandle; + } + + private float DrawAngleHandle(Transform transform, float radius, float offset, Handles.CapFunction capLeft, Handles.CapFunction capRight, ref float angle) + { + float old = angle; + float handleOffset = HandleUtility.GetHandleSize(transform.position) * offset; + float handleSize = HandleUtility.GetHandleSize(transform.position) * k_AngleCapSize; + + Quaternion rotLt = Quaternion.AngleAxis(-angle / 2, -transform.forward) * transform.rotation; + DrawAngleSlider2D(transform, rotLt, radius, handleOffset, capLeft, handleSize, true, true, true, ref angle); + + Quaternion rotRt = Quaternion.AngleAxis(angle / 2, -transform.forward) * transform.rotation; + DrawAngleSlider2D(transform, rotRt, radius, handleOffset, capRight, handleSize, false, true, true, ref angle); + + return angle - old; + } + + private void DrawRadiusArc(Transform transform, float radius, float angle, int steps, Handles.CapFunction capFunc, float capSize, bool even) + { + Handles.DrawWireArc(transform.position, transform.forward, Quaternion.AngleAxis(180 - angle / 2, transform.forward) * -transform.up, angle, radius); + } + + Handles.CapFunction GetCapFunc(Texture texture, bool isAngleHandle) + { + return (controlID, position, rotation, size, eventType) => Light2DEditorUtility.GUITextureCap(controlID, texture, position, rotation, size, eventType, isAngleHandle); + } + + private void DrawAngleHandles(Light2D light) + { + var oldColor = Handles.color; + Handles.color = Color.yellow; + + float outerAngle = light.pointLightOuterAngle; + float diff = DrawAngleHandle(light.transform, light.pointLightOuterRadius, k_AngleCapOffset, GetCapFunc(Styles.lightCapTopRight, true), GetCapFunc(Styles.lightCapBottomRight, true), ref outerAngle); + light.pointLightOuterAngle = outerAngle; + + if (diff != 0.0f) + light.pointLightInnerAngle = Mathf.Max(0.0f, light.pointLightInnerAngle + diff); + + float innerAngle = light.pointLightInnerAngle; + diff = DrawAngleHandle(light.transform, light.pointLightOuterRadius, -k_AngleCapOffset, GetCapFunc(Styles.lightCapTopLeft, true), GetCapFunc(Styles.lightCapBottomLeft, true), ref innerAngle); + light.pointLightInnerAngle = innerAngle; + + if (diff != 0.0f) + light.pointLightInnerAngle = light.pointLightInnerAngle < light.pointLightOuterAngle ? light.pointLightInnerAngle : light.pointLightOuterAngle; + + light.pointLightInnerAngle = Mathf.Min(light.pointLightInnerAngle, light.pointLightOuterAngle); + + Handles.color = oldColor; + } + + private void DrawRangeHandles(Light2D light) + { + var dummy = 0.0f; + bool radiusChanged = false; + Vector3 handlePos = Vector3.zero; + Quaternion rotLeft = Quaternion.AngleAxis(0, -light.transform.forward) * light.transform.rotation; + float handleOffset = HandleUtility.GetHandleSize(light.transform.position) * k_AngleCapOffsetSecondary; + float handleSize = HandleUtility.GetHandleSize(light.transform.position) * k_AngleCapSize; + + var oldColor = Handles.color; + Handles.color = Color.yellow; + + float outerRadius = light.pointLightOuterRadius; + EditorGUI.BeginChangeCheck(); + Vector3 returnPos = DrawAngleSlider2D(light.transform, rotLeft, outerRadius, -handleOffset, GetCapFunc(Styles.lightCapUp, false), handleSize, false, false, false, ref dummy); + if (EditorGUI.EndChangeCheck()) + { + var vec = (returnPos - light.transform.position).normalized; + light.transform.up = new Vector3(vec.x, vec.y, 0); + outerRadius = (returnPos - light.transform.position).magnitude; + outerRadius = outerRadius + handleOffset; + radiusChanged = true; + } + DrawRadiusArc(light.transform, light.pointLightOuterRadius, light.pointLightOuterAngle, 0, Handles.DotHandleCap, k_RangeCapSize, false); + + Handles.color = Color.gray; + float innerRadius = light.pointLightInnerRadius; + EditorGUI.BeginChangeCheck(); + returnPos = DrawAngleSlider2D(light.transform, rotLeft, innerRadius, handleOffset, GetCapFunc(Styles.lightCapDown, false), handleSize, true, false, false, ref dummy); + if (EditorGUI.EndChangeCheck()) + { + innerRadius = (returnPos - light.transform.position).magnitude; + innerRadius = innerRadius - handleOffset; + radiusChanged = true; + } + DrawRadiusArc(light.transform, light.pointLightInnerRadius, light.pointLightOuterAngle, 0, Handles.SphereHandleCap, k_InnerRangeCapSize, false); + + Handles.color = oldColor; + + if (radiusChanged) + { + light.pointLightInnerRadius = (outerRadius < innerRadius) ? outerRadius : innerRadius; + light.pointLightOuterRadius = (innerRadius > outerRadius) ? innerRadius : outerRadius; + } + } + + void OnSceneGUI() + { + var light = target as Light2D; + if (light == null) + return; + + Transform t = light.transform; + switch (light.lightType) + { + case Light2D.LightType.Point: + { + Undo.RecordObject(light.transform, "Edit Point Light Transform"); + Undo.RecordObject(light, "Edit Point Light"); + + DrawRangeHandles(light); + DrawAngleHandles(light); + + if (GUI.changed) + EditorUtility.SetDirty(light); + } + break; + case Light2D.LightType.Sprite: + { + var cookieSprite = light.lightCookieSprite; + if (cookieSprite != null) + { + Vector3 min = cookieSprite.bounds.min; + Vector3 max = cookieSprite.bounds.max; + + Vector3 v0 = t.TransformPoint(new Vector3(min.x, min.y)); + Vector3 v1 = t.TransformPoint(new Vector3(max.x, min.y)); + Vector3 v2 = t.TransformPoint(new Vector3(max.x, max.y)); + Vector3 v3 = t.TransformPoint(new Vector3(min.x, max.y)); + + Handles.DrawLine(v0, v1); + Handles.DrawLine(v1, v2); + Handles.DrawLine(v2, v3); + Handles.DrawLine(v3, v0); + } + } + break; + case Light2D.LightType.Freeform: + { + // Draw the falloff shape's outline + List falloffShape = light.GetFalloffShape(); + Handles.color = Color.white; + + for (int i = 0; i < falloffShape.Count - 1; ++i) + { + Handles.DrawLine(t.TransformPoint(falloffShape[i]), t.TransformPoint(falloffShape[i + 1])); + } + + if (falloffShape.Count > 0) + Handles.DrawLine(t.TransformPoint(falloffShape[falloffShape.Count - 1]), t.TransformPoint(falloffShape[0])); + + for (int i = 0; i < light.shapePath.Length - 1; ++i) + { + Handles.DrawLine(t.TransformPoint(light.shapePath[i]), + t.TransformPoint(light.shapePath[i + 1])); + } + + if (light.shapePath.Length > 0) + Handles.DrawLine(t.TransformPoint(light.shapePath[light.shapePath.Length - 1]), t.TransformPoint(light.shapePath[0])); + } + break; + } + } + + public override void OnInspectorGUI() + { + var meshChanged = false; + + serializedObject.Update(); + + UniversalRenderPipelineAsset asset = UniversalRenderPipeline.asset; + if (asset != null) + { + if (!Light2DEditorUtility.IsUsing2DRenderer()) + { + EditorGUILayout.HelpBox(Styles.asset2DUnassignedWarning); + } + else + { + if (m_LightType.intValue != (int)Light2D.DeprecatedLightType.Parametric) + meshChanged = DrawLightCommon(); + + switch (m_LightType.intValue) + { + case (int)Light2D.LightType.Point: + { + DrawSpotLight(serializedObject); + } + break; + case (int)Light2D.LightType.Freeform: + { + DrawShapeLight(serializedObject); + } + break; + case (int)Light2D.LightType.Sprite: + { + DrawSpriteLight(serializedObject); + } + break; + case (int)Light2D.LightType.Global: + { + DrawGlobalLight(serializedObject); + } + break; + case (int)Light2D.DeprecatedLightType.Parametric: + { + DrawParametricDeprecated(serializedObject); + } + break; + } + + AnalyticsTrackChanges(serializedObject); + if (serializedObject.ApplyModifiedProperties()) + { + if (meshChanged) + lightObject.UpdateMesh(true); + } + } + } + else + { + EditorGUILayout.HelpBox(Styles.renderPipelineUnassignedWarning); + + if (meshChanged) + lightObject.UpdateMesh(true); + } + } + } +} diff --git a/Editor/2D/Light2DEditor.cs.meta b/Editor/2D/Light2DEditor.cs.meta index df4461e..ecc3d46 100644 --- a/Editor/2D/Light2DEditor.cs.meta +++ b/Editor/2D/Light2DEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: c2bef50bb856f744080489123f6b3f84 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c2bef50bb856f744080489123f6b3f84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Light2DEditorUtility.cs b/Editor/2D/Light2DEditorUtility.cs index 3ed3d2f..4a03f07 100644 --- a/Editor/2D/Light2DEditorUtility.cs +++ b/Editor/2D/Light2DEditorUtility.cs @@ -1,122 +1,122 @@ -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - internal static class Light2DEditorUtility - { - static Material s_TexCapMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/Internal-GUITexture")); - - static internal void GUITextureCap(int controlID, Texture texture, Vector3 position, Quaternion rotation, float size, EventType eventType, bool isAngleHandle) - { - switch (eventType) - { - case (EventType.Layout): - { - Vector2 size2 = Vector2.one * size * 0.5f; - if (isAngleHandle) - size2.x = 0.0f; - - HandleUtility.AddControl(controlID, DistanceToRectangle(position, rotation, size2)); - break; - } - - case (EventType.Repaint): - { - s_TexCapMaterial.mainTexture = texture; - s_TexCapMaterial.SetPass(0); - - float w = texture.width; - float h = texture.height; - float max = Mathf.Max(w, h); - Vector3 scale = new Vector2(w / max, h / max) * size * 0.5f; - - if (Camera.current == null) - scale.y *= -1f; - - Matrix4x4 matrix = new Matrix4x4(); - matrix.SetTRS(position, rotation, scale); - - Graphics.DrawMeshNow(RenderingUtils.fullscreenMesh, matrix); - } - break; - } - } - - static float DistanceToRectangle(Vector3 position, Quaternion rotation, Vector2 size) - { - Vector3[] points = { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero }; - Vector3 sideways = rotation * new Vector3(size.x, 0, 0); - Vector3 up = rotation * new Vector3(0, size.y, 0); - - points[0] = HandleUtility.WorldToGUIPoint(position + sideways + up); - points[1] = HandleUtility.WorldToGUIPoint(position + sideways - up); - points[2] = HandleUtility.WorldToGUIPoint(position - sideways - up); - points[3] = HandleUtility.WorldToGUIPoint(position - sideways + up); - points[4] = points[0]; - - Vector2 pos = Event.current.mousePosition; - bool oddNodes = false; - int j = 4; - - for (int i = 0; i < 5; ++i) - { - if ((points[i].y > pos.y) != (points[j].y > pos.y)) - { - if (pos.x < (points[j].x - points[i].x) * (pos.y - points[i].y) / (points[j].y - points[i].y) + points[i].x) - oddNodes = !oddNodes; - } - - j = i; - } - - if (!oddNodes) - { - // Distance to closest edge (not so fast) - float dist, closestDist = -1f; - j = 1; - - for (int i = 0; i < 4; ++i) - { - dist = HandleUtility.DistancePointToLineSegment(pos, points[i], points[j++]); - if (dist < closestDist || closestDist < 0) - closestDist = dist; - } - - return closestDist; - } - else - return 0; - } - - public static Renderer2DData GetRenderer2DData() - { - UniversalRenderPipelineAsset pipelineAsset = UniversalRenderPipeline.asset; - if (pipelineAsset == null) - return null; - - // try get the default - Renderer2DData rendererData = pipelineAsset.scriptableRendererData as Renderer2DData; - if(rendererData == null) - { - foreach (Camera camera in Camera.allCameras) - { - UniversalAdditionalCameraData additionalCameraData = camera.GetComponent(); - ScriptableRenderer renderer = additionalCameraData?.scriptableRenderer; - Renderer2D renderer2D = renderer as Renderer2D; - if (renderer2D != null) - return renderer2D.GetRenderer2DData(); - } - } - - return rendererData; - } - - public static bool IsUsing2DRenderer() - { - return GetRenderer2DData() != null; - } - } -} +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + internal static class Light2DEditorUtility + { + static Material s_TexCapMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/Internal-GUITexture")); + + static internal void GUITextureCap(int controlID, Texture texture, Vector3 position, Quaternion rotation, float size, EventType eventType, bool isAngleHandle) + { + switch (eventType) + { + case (EventType.Layout): + { + Vector2 size2 = Vector2.one * size * 0.5f; + if (isAngleHandle) + size2.x = 0.0f; + + HandleUtility.AddControl(controlID, DistanceToRectangle(position, rotation, size2)); + break; + } + + case (EventType.Repaint): + { + s_TexCapMaterial.mainTexture = texture; + s_TexCapMaterial.SetPass(0); + + float w = texture.width; + float h = texture.height; + float max = Mathf.Max(w, h); + Vector3 scale = new Vector2(w / max, h / max) * size * 0.5f; + + if (Camera.current == null) + scale.y *= -1f; + + Matrix4x4 matrix = new Matrix4x4(); + matrix.SetTRS(position, rotation, scale); + + Graphics.DrawMeshNow(RenderingUtils.fullscreenMesh, matrix); + } + break; + } + } + + static float DistanceToRectangle(Vector3 position, Quaternion rotation, Vector2 size) + { + Vector3[] points = { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero }; + Vector3 sideways = rotation * new Vector3(size.x, 0, 0); + Vector3 up = rotation * new Vector3(0, size.y, 0); + + points[0] = HandleUtility.WorldToGUIPoint(position + sideways + up); + points[1] = HandleUtility.WorldToGUIPoint(position + sideways - up); + points[2] = HandleUtility.WorldToGUIPoint(position - sideways - up); + points[3] = HandleUtility.WorldToGUIPoint(position - sideways + up); + points[4] = points[0]; + + Vector2 pos = Event.current.mousePosition; + bool oddNodes = false; + int j = 4; + + for (int i = 0; i < 5; ++i) + { + if ((points[i].y > pos.y) != (points[j].y > pos.y)) + { + if (pos.x < (points[j].x - points[i].x) * (pos.y - points[i].y) / (points[j].y - points[i].y) + points[i].x) + oddNodes = !oddNodes; + } + + j = i; + } + + if (!oddNodes) + { + // Distance to closest edge (not so fast) + float dist, closestDist = -1f; + j = 1; + + for (int i = 0; i < 4; ++i) + { + dist = HandleUtility.DistancePointToLineSegment(pos, points[i], points[j++]); + if (dist < closestDist || closestDist < 0) + closestDist = dist; + } + + return closestDist; + } + else + return 0; + } + + public static Renderer2DData GetRenderer2DData() + { + UniversalRenderPipelineAsset pipelineAsset = UniversalRenderPipeline.asset; + if (pipelineAsset == null) + return null; + + // try get the default + Renderer2DData rendererData = pipelineAsset.scriptableRendererData as Renderer2DData; + if (rendererData == null) + { + foreach (Camera camera in Camera.allCameras) + { + UniversalAdditionalCameraData additionalCameraData = camera.GetComponent(); + ScriptableRenderer renderer = additionalCameraData?.scriptableRenderer; + Renderer2D renderer2D = renderer as Renderer2D; + if (renderer2D != null) + return renderer2D.GetRenderer2DData(); + } + } + + + return rendererData; + } + + public static bool IsUsing2DRenderer() + { + return GetRenderer2DData() != null; + } + } +} diff --git a/Editor/2D/Light2DEditorUtility.cs.meta b/Editor/2D/Light2DEditorUtility.cs.meta index 90a351d..1395b42 100644 --- a/Editor/2D/Light2DEditorUtility.cs.meta +++ b/Editor/2D/Light2DEditorUtility.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 62e1d3960d9dba84780a633cbb9f63c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 62e1d3960d9dba84780a633cbb9f63c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/PixelPerfectCameraEditor.cs b/Editor/2D/PixelPerfectCameraEditor.cs index 7522d82..b7ec0a6 100644 --- a/Editor/2D/PixelPerfectCameraEditor.cs +++ b/Editor/2D/PixelPerfectCameraEditor.cs @@ -1,280 +1,256 @@ -using System; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - [CustomEditor(typeof(PixelPerfectCamera))] - class PixelPerfectCameraEditor : Editor - { - private class Style - { - public GUIContent x = new GUIContent("X"); - public GUIContent y = new GUIContent("Y"); - public GUIContent assetsPPU = new GUIContent("Assets Pixels Per Unit", "The amount of pixels that make up one unit of the Scene. Set this value to match the PPU value of Sprites in the Scene."); - public GUIContent refRes = new GUIContent("Reference Resolution", "The original resolution the Assets are designed for."); - public GUIContent upscaleRT = new GUIContent("Upscale Render Texture", "If enabled, the Scene is rendered as close as possible to the Reference Resolution while maintaining the screen aspect ratio, then upscaled to fit the full screen."); - public GUIContent pixelSnapping = new GUIContent("Pixel Snapping", "If enabled, Sprite Renderers are snapped to a grid in world space at render-time. Grid size is based on the Assets Pixels Per Unit value. This does not affect GameObjects' Transform positions."); - public GUIContent cropFrame = new GUIContent("Crop Frame", "Crops the viewport to match the Reference Resolution, along the checked axis. Black bars will be added to fit the screen aspect ratio."); - public GUIContent stretchFill = new GUIContent("Stretch Fill", "If enabled, expands the viewport to fit the screen resolution while maintaining the viewport aspect ratio."); - public GUIContent currentPixelRatio = new GUIContent("Current Pixel Ratio", "Ratio of the rendered Sprites compared to their original size."); - public GUIContent runInEditMode = new GUIContent("Run In Edit Mode", "Enable this to preview Camera setting changes in Edit Mode. This will cause constant changes to the Scene while active."); - public const string cameraStackingWarning = "Pixel Perfect Camera won't function properly if stacked with another camera."; - - public GUIStyle centeredLabel; - - public Style() - { - centeredLabel = new GUIStyle(EditorStyles.label); - centeredLabel.alignment = TextAnchor.MiddleCenter; - } - } - - private static Style m_Style; - - private const float k_SingleLetterLabelWidth = 15.0f; - private const float k_DottedLineSpacing = 2.5f; - - private SerializedProperty m_AssetsPPU; - private SerializedProperty m_RefResX; - private SerializedProperty m_RefResY; - private SerializedProperty m_UpscaleRT; - private SerializedProperty m_PixelSnapping; - private SerializedProperty m_CropFrameY; - private SerializedProperty m_CropFrameX; - private SerializedProperty m_StretchFill; - - private Vector2 m_GameViewSize = Vector2.zero; - private GUIContent m_CurrentPixelRatioValue; - bool m_CameraStacking; - - private void LazyInit() - { - if (m_Style == null) - m_Style = new Style(); - - if (m_CurrentPixelRatioValue == null) - m_CurrentPixelRatioValue = new GUIContent(); - } - - void CheckForCameraStacking() - { - m_CameraStacking = false; - - PixelPerfectCamera obj = target as PixelPerfectCamera; - UniversalAdditionalCameraData cameraData = null; - obj?.TryGetComponent(out cameraData); - - if (cameraData == null) - return; - - if (cameraData.renderType == CameraRenderType.Base) - { - var cameraStack = cameraData.cameraStack; - m_CameraStacking = cameraStack != null ? cameraStack.Count > 0 : false; - } - else if (cameraData.renderType == CameraRenderType.Overlay) - m_CameraStacking = true; - } - - public void OnEnable() - { - m_AssetsPPU = serializedObject.FindProperty("m_AssetsPPU"); - m_RefResX = serializedObject.FindProperty("m_RefResolutionX"); - m_RefResY = serializedObject.FindProperty("m_RefResolutionY"); - m_UpscaleRT = serializedObject.FindProperty("m_UpscaleRT"); - m_PixelSnapping = serializedObject.FindProperty("m_PixelSnapping"); - m_CropFrameY = serializedObject.FindProperty("m_CropFrameY"); - m_CropFrameX = serializedObject.FindProperty("m_CropFrameX"); - m_StretchFill = serializedObject.FindProperty("m_StretchFill"); - } - - public override bool RequiresConstantRepaint() - { - PixelPerfectCamera obj = target as PixelPerfectCamera; - if (obj == null || !obj.enabled) - return false; - - // If game view size changes, we need to force a repaint of the inspector as the pixel ratio value may change accordingly. - Vector2 gameViewSize = Handles.GetMainGameViewSize(); - if (gameViewSize != m_GameViewSize) - { - m_GameViewSize = gameViewSize; - return true; - } - else - return false; - } - - public override void OnInspectorGUI() - { - LazyInit(); - - float originalLabelWidth = EditorGUIUtility.labelWidth; - - serializedObject.Update(); - - if (Event.current.type == EventType.Layout) - CheckForCameraStacking(); - - if (m_CameraStacking) - EditorGUILayout.HelpBox(Style.cameraStackingWarning, MessageType.Warning); - - EditorGUILayout.PropertyField(m_AssetsPPU, m_Style.assetsPPU); - if (m_AssetsPPU.intValue <= 0) - m_AssetsPPU.intValue = 1; - - EditorGUILayout.BeginHorizontal(); - { - EditorGUILayout.PrefixLabel(m_Style.refRes); - - EditorGUIUtility.labelWidth = k_SingleLetterLabelWidth * (EditorGUI.indentLevel + 1); - - EditorGUILayout.PropertyField(m_RefResX, m_Style.x); - if (m_RefResX.intValue <= 0) - m_RefResX.intValue = 1; - - EditorGUILayout.PropertyField(m_RefResY, m_Style.y); - if (m_RefResY.intValue <= 0) - m_RefResY.intValue = 1; - - EditorGUIUtility.labelWidth = originalLabelWidth; - } - EditorGUILayout.EndHorizontal(); - - EditorGUILayout.PropertyField(m_UpscaleRT, m_Style.upscaleRT); - if (!m_UpscaleRT.boolValue) - { - EditorGUI.indentLevel++; - EditorGUILayout.PropertyField(m_PixelSnapping, m_Style.pixelSnapping); - EditorGUI.indentLevel--; - } - - EditorGUILayout.BeginHorizontal(); - { - EditorGUILayout.PrefixLabel(m_Style.cropFrame); - - EditorGUIUtility.labelWidth = k_SingleLetterLabelWidth * (EditorGUI.indentLevel + 1); - EditorGUILayout.PropertyField(m_CropFrameX, m_Style.x, GUILayout.MaxWidth(40.0f)); - EditorGUILayout.PropertyField(m_CropFrameY, m_Style.y); - EditorGUIUtility.labelWidth = originalLabelWidth; - } - EditorGUILayout.EndHorizontal(); - - if (m_CropFrameY.boolValue && m_CropFrameX.boolValue) - { - EditorGUI.indentLevel++; - EditorGUILayout.PropertyField(m_StretchFill, m_Style.stretchFill); - EditorGUI.indentLevel--; - } - - serializedObject.ApplyModifiedProperties(); - - PixelPerfectCamera obj = target as PixelPerfectCamera; - - if (obj != null) - { - EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying || !obj.isActiveAndEnabled); - EditorGUI.BeginChangeCheck(); - - bool runInEditMode = EditorGUILayout.Toggle(obj.runInEditMode, GUI.skin.button, GUILayout.Width(110.0f)); - GUI.Label(GUILayoutUtility.GetLastRect(), m_Style.runInEditMode, m_Style.centeredLabel); - - if (EditorGUI.EndChangeCheck()) - { - obj.runInEditMode = runInEditMode; - - if (runInEditMode) - obj.GetComponent().Render(); - else - obj.OnDisable(); - } - - EditorGUI.EndDisabledGroup(); - - if (obj.isActiveAndEnabled && (EditorApplication.isPlaying || obj.runInEditMode)) - { - if (Event.current.type == EventType.Layout) - m_CurrentPixelRatioValue.text = string.Format("{0}:1", obj.pixelRatio); - - EditorGUI.BeginDisabledGroup(true); - EditorGUILayout.LabelField(m_Style.currentPixelRatio, m_CurrentPixelRatioValue); - EditorGUI.EndDisabledGroup(); - } - } - } - - void OnSceneGUI() - { - PixelPerfectCamera obj = target as PixelPerfectCamera; - if (obj == null) - return; - - Camera camera = obj.GetComponent(); - - // Show a green rect in scene view that represents the visible area when the pixel perfect correction takes effect in play mode. - Vector2 gameViewSize = Handles.GetMainGameViewSize(); - int gameViewWidth = (int)gameViewSize.x; - int gameViewHeight = (int)gameViewSize.y; - int zoom = Math.Max(1, Math.Min(gameViewHeight / obj.refResolutionY, gameViewWidth / obj.refResolutionX)); - - float verticalOrthoSize; - float horizontalOrthoSize; - - if (obj.cropFrameY && obj.cropFrameX) - { - verticalOrthoSize = obj.refResolutionY * 0.5f / obj.assetsPPU; - horizontalOrthoSize = verticalOrthoSize * ((float)obj.refResolutionX / obj.refResolutionY); - } - else if (obj.cropFrameY) - { - verticalOrthoSize = obj.refResolutionY * 0.5f / obj.assetsPPU; - horizontalOrthoSize = verticalOrthoSize * ((float)gameViewWidth / (zoom * obj.refResolutionY)); - } - else if (obj.cropFrameX) - { - horizontalOrthoSize = obj.refResolutionX * 0.5f / obj.assetsPPU; - verticalOrthoSize = horizontalOrthoSize / (zoom * obj.refResolutionX / (float)gameViewHeight); - } - else - { - verticalOrthoSize = gameViewHeight * 0.5f / (zoom * obj.assetsPPU); - horizontalOrthoSize = verticalOrthoSize * camera.aspect; - } - - Handles.color = Color.green; - - Vector3 cameraPosition = camera.transform.position; - Vector3 p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); - Vector3 p2 = cameraPosition + new Vector3(horizontalOrthoSize, verticalOrthoSize, 0.0f); - Handles.DrawLine(p1, p2); - - p1 = cameraPosition + new Vector3(horizontalOrthoSize, -verticalOrthoSize, 0.0f); - Handles.DrawLine(p2, p1); - - p2 = cameraPosition + new Vector3(-horizontalOrthoSize, -verticalOrthoSize, 0.0f); - Handles.DrawLine(p1, p2); - - p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); - Handles.DrawLine(p2, p1); - - // Show a green dotted rect in scene view that represents the area defined by the reference resolution. - horizontalOrthoSize = obj.refResolutionX * 0.5f / obj.assetsPPU; - verticalOrthoSize = obj.refResolutionY * 0.5f / obj.assetsPPU; - - p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); - p2 = cameraPosition + new Vector3(horizontalOrthoSize, verticalOrthoSize, 0.0f); - Handles.DrawDottedLine(p1, p2, k_DottedLineSpacing); - - p1 = cameraPosition + new Vector3(horizontalOrthoSize, -verticalOrthoSize, 0.0f); - Handles.DrawDottedLine(p2, p1, k_DottedLineSpacing); - - p2 = cameraPosition + new Vector3(-horizontalOrthoSize, -verticalOrthoSize, 0.0f); - Handles.DrawDottedLine(p1, p2, k_DottedLineSpacing); - - p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); - Handles.DrawDottedLine(p2, p1, k_DottedLineSpacing); - } - } -} +using System; +using UnityEngine; +using UnityEngine.Experimental.Rendering.Universal; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + [CustomEditor(typeof(PixelPerfectCamera))] + class PixelPerfectCameraEditor : Editor + { + private class Style + { + public GUIContent x = new GUIContent("X"); + public GUIContent y = new GUIContent("Y"); + public GUIContent assetsPPU = new GUIContent("Assets Pixels Per Unit", "The amount of pixels that make up one unit of the Scene. Set this value to match the PPU value of Sprites in the Scene."); + public GUIContent refRes = new GUIContent("Reference Resolution", "The original resolution the Assets are designed for."); + public GUIContent gridSnapping = new GUIContent("Grid Snapping", "Sets the snapping behavior for the camera and sprites."); + public GUIContent cropFrame = new GUIContent("Crop Frame", "Crops the viewport to match the Reference Resolution, along the checked axis. Black bars will be added to fit the screen aspect ratio."); + public GUIContent stretchFill = new GUIContent("Stretch Fill", "If enabled, expands the viewport to fit the screen resolution while maintaining the viewport aspect ratio."); + public GUIContent currentPixelRatio = new GUIContent("Current Pixel Ratio", "Ratio of the rendered Sprites compared to their original size."); + public GUIContent runInEditMode = new GUIContent("Run In Edit Mode", "Enable this to preview Camera setting changes in Edit Mode. This will cause constant changes to the Scene while active."); + public const string cameraStackingWarning = "Pixel Perfect Camera won't function properly if stacked with another camera."; + public const string nonRenderer2DError = "Pixel Perfect Camera requires a camera using a 2D Renderer."; + + public GUIStyle centeredLabel; + + public Style() + { + centeredLabel = new GUIStyle(EditorStyles.label); + centeredLabel.alignment = TextAnchor.MiddleCenter; + } + } + + private static Style m_Style; + + private const float k_SingleLetterLabelWidth = 15.0f; + private const float k_DottedLineSpacing = 2.5f; + + private SerializedProperty m_AssetsPPU; + private SerializedProperty m_RefResX; + private SerializedProperty m_RefResY; + private SerializedProperty m_CropFrame; + private SerializedProperty m_GridSnapping; + + private Vector2 m_GameViewSize = Vector2.zero; + private GUIContent m_CurrentPixelRatioValue; + bool m_CameraStacking; + + private void LazyInit() + { + if (m_Style == null) + m_Style = new Style(); + + if (m_CurrentPixelRatioValue == null) + m_CurrentPixelRatioValue = new GUIContent(); + } + + bool UsingRenderer2D() + { + PixelPerfectCamera obj = target as PixelPerfectCamera; + UniversalAdditionalCameraData cameraData = null; + obj?.TryGetComponent(out cameraData); + + if (cameraData != null) + { + Renderer2D renderer2D = cameraData.scriptableRenderer as Renderer2D; + if (renderer2D != null) + return true; + } + + return false; + } + + void CheckForCameraStacking() + { + m_CameraStacking = false; + + PixelPerfectCamera obj = target as PixelPerfectCamera; + UniversalAdditionalCameraData cameraData = null; + obj?.TryGetComponent(out cameraData); + + if (cameraData == null) + return; + + if (cameraData.renderType == CameraRenderType.Base) + { + var cameraStack = cameraData.cameraStack; + m_CameraStacking = cameraStack != null ? cameraStack.Count > 0 : false; + } + else if (cameraData.renderType == CameraRenderType.Overlay) + m_CameraStacking = true; + } + + public void OnEnable() + { + m_AssetsPPU = serializedObject.FindProperty("m_AssetsPPU"); + m_RefResX = serializedObject.FindProperty("m_RefResolutionX"); + m_RefResY = serializedObject.FindProperty("m_RefResolutionY"); + m_CropFrame = serializedObject.FindProperty("m_CropFrame"); + m_GridSnapping = serializedObject.FindProperty("m_GridSnapping"); + } + + public override bool RequiresConstantRepaint() + { + PixelPerfectCamera obj = target as PixelPerfectCamera; + if (obj == null || !obj.enabled) + return false; + + // If game view size changes, we need to force a repaint of the inspector as the pixel ratio value may change accordingly. + Vector2 gameViewSize = Handles.GetMainGameViewSize(); + if (gameViewSize != m_GameViewSize) + { + m_GameViewSize = gameViewSize; + return true; + } + else + return false; + } + + public override void OnInspectorGUI() + { + LazyInit(); + + if (!UsingRenderer2D()) + { + EditorGUILayout.HelpBox(Style.nonRenderer2DError, MessageType.Error); + return; + } + + float originalLabelWidth = EditorGUIUtility.labelWidth; + + serializedObject.Update(); + + if (Event.current.type == EventType.Layout) + CheckForCameraStacking(); + + if (m_CameraStacking) + EditorGUILayout.HelpBox(Style.cameraStackingWarning, MessageType.Warning); + + EditorGUILayout.PropertyField(m_AssetsPPU, m_Style.assetsPPU); + if (m_AssetsPPU.intValue <= 0) + m_AssetsPPU.intValue = 1; + + EditorGUILayout.BeginHorizontal(); + { + EditorGUILayout.PrefixLabel(m_Style.refRes); + + EditorGUIUtility.labelWidth = k_SingleLetterLabelWidth * (EditorGUI.indentLevel + 1); + + EditorGUILayout.PropertyField(m_RefResX, m_Style.x); + if (m_RefResX.intValue <= 0) + m_RefResX.intValue = 1; + + EditorGUILayout.PropertyField(m_RefResY, m_Style.y); + if (m_RefResY.intValue <= 0) + m_RefResY.intValue = 1; + + EditorGUIUtility.labelWidth = originalLabelWidth; + } + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.PropertyField(m_CropFrame, m_Style.cropFrame); + EditorGUILayout.PropertyField(m_GridSnapping, m_Style.gridSnapping); + + + serializedObject.ApplyModifiedProperties(); + + PixelPerfectCamera obj = target as PixelPerfectCamera; + + if (obj != null) + { + if (obj.isActiveAndEnabled && (EditorApplication.isPlaying || obj.runInEditMode)) + { + if (Event.current.type == EventType.Layout) + m_CurrentPixelRatioValue.text = string.Format("{0}:1", obj.pixelRatio); + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.LabelField(m_Style.currentPixelRatio, m_CurrentPixelRatioValue); + EditorGUI.EndDisabledGroup(); + } + } + } + + void OnSceneGUI() + { + PixelPerfectCamera obj = target as PixelPerfectCamera; + if (obj == null) + return; + + Camera camera = obj.GetComponent(); + + // Show a green rect in scene view that represents the visible area when the pixel perfect correction takes effect in play mode. + Vector2 gameViewSize = Handles.GetMainGameViewSize(); + int gameViewWidth = (int)gameViewSize.x; + int gameViewHeight = (int)gameViewSize.y; + int zoom = Math.Max(1, Math.Min(gameViewHeight / obj.refResolutionY, gameViewWidth / obj.refResolutionX)); + + float verticalOrthoSize; + float horizontalOrthoSize; + + if (obj.cropFrame == PixelPerfectCamera.CropFrame.StretchFill || obj.cropFrame == PixelPerfectCamera.CropFrame.Windowbox) + { + verticalOrthoSize = obj.refResolutionY * 0.5f / obj.assetsPPU; + horizontalOrthoSize = verticalOrthoSize * ((float)obj.refResolutionX / obj.refResolutionY); + } + else if (obj.cropFrame == PixelPerfectCamera.CropFrame.Letterbox) + { + verticalOrthoSize = obj.refResolutionY * 0.5f / obj.assetsPPU; + horizontalOrthoSize = verticalOrthoSize * ((float)gameViewWidth / (zoom * obj.refResolutionY)); + } + else if (obj.cropFrame == PixelPerfectCamera.CropFrame.Pillarbox) + { + horizontalOrthoSize = obj.refResolutionX * 0.5f / obj.assetsPPU; + verticalOrthoSize = horizontalOrthoSize / (zoom * obj.refResolutionX / (float)gameViewHeight); + } + else + { + verticalOrthoSize = gameViewHeight * 0.5f / (zoom * obj.assetsPPU); + horizontalOrthoSize = verticalOrthoSize * camera.aspect; + } + + Handles.color = Color.green; + + Vector3 cameraPosition = camera.transform.position; + Vector3 p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); + Vector3 p2 = cameraPosition + new Vector3(horizontalOrthoSize, verticalOrthoSize, 0.0f); + Handles.DrawLine(p1, p2); + + p1 = cameraPosition + new Vector3(horizontalOrthoSize, -verticalOrthoSize, 0.0f); + Handles.DrawLine(p2, p1); + + p2 = cameraPosition + new Vector3(-horizontalOrthoSize, -verticalOrthoSize, 0.0f); + Handles.DrawLine(p1, p2); + + p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); + Handles.DrawLine(p2, p1); + + // Show a green dotted rect in scene view that represents the area defined by the reference resolution. + horizontalOrthoSize = obj.refResolutionX * 0.5f / obj.assetsPPU; + verticalOrthoSize = obj.refResolutionY * 0.5f / obj.assetsPPU; + + p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); + p2 = cameraPosition + new Vector3(horizontalOrthoSize, verticalOrthoSize, 0.0f); + Handles.DrawDottedLine(p1, p2, k_DottedLineSpacing); + + p1 = cameraPosition + new Vector3(horizontalOrthoSize, -verticalOrthoSize, 0.0f); + Handles.DrawDottedLine(p2, p1, k_DottedLineSpacing); + + p2 = cameraPosition + new Vector3(-horizontalOrthoSize, -verticalOrthoSize, 0.0f); + Handles.DrawDottedLine(p1, p2, k_DottedLineSpacing); + + p1 = cameraPosition + new Vector3(-horizontalOrthoSize, verticalOrthoSize, 0.0f); + Handles.DrawDottedLine(p2, p1, k_DottedLineSpacing); + } + } +} diff --git a/Editor/2D/PixelPerfectCameraEditor.cs.meta b/Editor/2D/PixelPerfectCameraEditor.cs.meta index 004855d..c7119fe 100644 --- a/Editor/2D/PixelPerfectCameraEditor.cs.meta +++ b/Editor/2D/PixelPerfectCameraEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 210f441e9bc1d0c4888c4369d2c0859f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 210f441e9bc1d0c4888c4369d2c0859f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Renderer2DAnalytics.cs b/Editor/2D/Renderer2DAnalytics.cs index 5ddb62b..3068be5 100644 --- a/Editor/2D/Renderer2DAnalytics.cs +++ b/Editor/2D/Renderer2DAnalytics.cs @@ -1,80 +1,80 @@ -using System; -using UnityEngine; -using UnityEngine.Analytics; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal.Analytics -{ - struct AnalyticsDataTypes - { - public const string k_LightDataString = "u2drendererlights"; - public const string k_Renderer2DDataString = "u2drendererdata"; - } - - internal interface IAnalyticsData { }; - - [Serializable] - internal struct Light2DData : IAnalyticsData - { - [SerializeField] - public bool was_create_event; - [SerializeField] - public int instance_id; - [SerializeField] - public Light2D.LightType light_type; - }; - - - [Serializable] - internal struct RendererAssetData : IAnalyticsData - { - [SerializeField] - public bool was_create_event; - [SerializeField] - public int instance_id; - [SerializeField] - public int blending_layers_count; - [SerializeField] - public int blending_modes_used; - } - - - interface IAnalytics - { - AnalyticsResult SendData(string eventString, IAnalyticsData data); - } - - [InitializeOnLoad] - internal class Renderer2DAnalytics : IAnalytics - { - const int k_MaxEventsPerHour = 1000; - const int k_MaxNumberOfElements = 1000; - const string k_VendorKey = "unity.renderpipelines.universal.editor"; - const int k_Version = 1; - static Renderer2DAnalytics m_Instance = new Renderer2DAnalytics(); - static bool s_Initialize = false; - public static Renderer2DAnalytics instance - { - get - { - if (m_Instance == null) - m_Instance = new Renderer2DAnalytics(); - - return m_Instance; - } - } - - public AnalyticsResult SendData(string eventString, IAnalyticsData data) - { - //Debug.Log("Sent Data " + JsonUtility.ToJson(data)); - if (false == s_Initialize) - { - EditorAnalytics.RegisterEventWithLimit(AnalyticsDataTypes.k_LightDataString, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey, k_Version); - EditorAnalytics.RegisterEventWithLimit(AnalyticsDataTypes.k_Renderer2DDataString, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey, k_Version); - s_Initialize = true; - } - - return EditorAnalytics.SendEventWithLimit(eventString, data, k_Version); - } - } -} +using System; +using UnityEngine; +using UnityEngine.Analytics; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Analytics +{ + struct AnalyticsDataTypes + { + public const string k_LightDataString = "u2drendererlights"; + public const string k_Renderer2DDataString = "u2drendererdata"; + } + + internal interface IAnalyticsData { }; + + [Serializable] + internal struct Light2DData : IAnalyticsData + { + [SerializeField] + public bool was_create_event; + [SerializeField] + public int instance_id; + [SerializeField] + public Light2D.LightType light_type; + }; + + + [Serializable] + internal struct RendererAssetData : IAnalyticsData + { + [SerializeField] + public bool was_create_event; + [SerializeField] + public int instance_id; + [SerializeField] + public int blending_layers_count; + [SerializeField] + public int blending_modes_used; + } + + + interface IAnalytics + { + AnalyticsResult SendData(string eventString, IAnalyticsData data); + } + + [InitializeOnLoad] + internal class Renderer2DAnalytics : IAnalytics + { + const int k_MaxEventsPerHour = 1000; + const int k_MaxNumberOfElements = 1000; + const string k_VendorKey = "unity.renderpipelines.universal.editor"; + const int k_Version = 1; + static Renderer2DAnalytics m_Instance = new Renderer2DAnalytics(); + static bool s_Initialize = false; + public static Renderer2DAnalytics instance + { + get + { + if (m_Instance == null) + m_Instance = new Renderer2DAnalytics(); + + return m_Instance; + } + } + + public AnalyticsResult SendData(string eventString, IAnalyticsData data) + { + //Debug.Log("Sent Data " + JsonUtility.ToJson(data)); + if (false == s_Initialize) + { + EditorAnalytics.RegisterEventWithLimit(AnalyticsDataTypes.k_LightDataString, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey, k_Version); + EditorAnalytics.RegisterEventWithLimit(AnalyticsDataTypes.k_Renderer2DDataString, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey, k_Version); + s_Initialize = true; + } + + return EditorAnalytics.SendEventWithLimit(eventString, data, k_Version); + } + } +} diff --git a/Editor/2D/Renderer2DAnalytics.cs.meta b/Editor/2D/Renderer2DAnalytics.cs.meta index 7598673..09574a2 100644 --- a/Editor/2D/Renderer2DAnalytics.cs.meta +++ b/Editor/2D/Renderer2DAnalytics.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 0db64c12471d19e4fb66ecb17a2edd90 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 0db64c12471d19e4fb66ecb17a2edd90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Renderer2DDataEditor.cs b/Editor/2D/Renderer2DDataEditor.cs index da05288..2fa9cf7 100644 --- a/Editor/2D/Renderer2DDataEditor.cs +++ b/Editor/2D/Renderer2DDataEditor.cs @@ -1,188 +1,275 @@ -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - [CustomEditor(typeof(Renderer2DData), true)] - internal class Renderer2DDataEditor : Editor - { - class Styles - { - public static readonly GUIContent transparencySortMode = EditorGUIUtility.TrTextContent("Transparency Sort Mode", "Default sorting mode used for transparent objects"); - public static readonly GUIContent transparencySortAxis = EditorGUIUtility.TrTextContent("Transparency Sort Axis", "Axis used for custom axis sorting mode"); - public static readonly GUIContent hdrEmulationScale = EditorGUIUtility.TrTextContent("HDR Emulation Scale", "Describes the scaling used by lighting to remap dynamic range between LDR and HDR"); - public static readonly GUIContent lightBlendStyles = EditorGUIUtility.TrTextContent("Light Blend Styles", "A Light Blend Style is a collection of properties that describe a particular way of applying lighting."); - public static readonly GUIContent defaultMaterialType = EditorGUIUtility.TrTextContent("Default Material Type", "Material to use when adding new objects to a scene"); - public static readonly GUIContent defaultCustomMaterial = EditorGUIUtility.TrTextContent("Default Custom Material", "Material to use when adding new objects to a scene"); - - public static readonly GUIContent name = EditorGUIUtility.TrTextContent("Name"); - public static readonly GUIContent maskTextureChannel = EditorGUIUtility.TrTextContent("Mask Texture Channel", "Which channel of the mask texture will affect this Light Blend Style."); - public static readonly GUIContent renderTextureScale = EditorGUIUtility.TrTextContent("Render Texture Scale", "The resolution of the lighting buffer relative to the screen resolution. 1.0 means full screen size."); - public static readonly GUIContent blendMode = EditorGUIUtility.TrTextContent("Blend Mode", "How the lighting should be blended with the main color of the objects."); - public static readonly GUIContent customBlendFactors = EditorGUIUtility.TrTextContent("Custom Blend Factors"); - public static readonly GUIContent blendFactorMultiplicative = EditorGUIUtility.TrTextContent("Multiplicative"); - public static readonly GUIContent blendFactorAdditive = EditorGUIUtility.TrTextContent("Additive"); - public static readonly GUIContent useDepthStencilBuffer = EditorGUIUtility.TrTextContent("Use Depth/Stencil Buffer", "Uncheck this when you are certain you don't use any feature that requires the depth/stencil buffer (e.g. Sprite Mask). Not using the depth/stencil buffer may improve performance, especially on mobile platforms."); - public static readonly GUIContent postProcessData = EditorGUIUtility.TrTextContent("Post-processing Data", "Resources (textures, shaders, etc.) required by post-processing effects."); - } - - struct LightBlendStyleProps - { - public SerializedProperty name; - public SerializedProperty maskTextureChannel; - public SerializedProperty renderTextureScale; - public SerializedProperty blendMode; - public SerializedProperty blendFactorMultiplicative; - public SerializedProperty blendFactorAdditive; - } - - - SerializedProperty m_TransparencySortMode; - SerializedProperty m_TransparencySortAxis; - SerializedProperty m_HDREmulationScale; - SerializedProperty m_LightBlendStyles; - LightBlendStyleProps[] m_LightBlendStylePropsArray; - SerializedProperty m_UseDepthStencilBuffer; - SerializedProperty m_PostProcessData; - SerializedProperty m_DefaultMaterialType; - SerializedProperty m_DefaultCustomMaterial; - - Analytics.Renderer2DAnalytics m_Analytics = Analytics.Renderer2DAnalytics.instance; - Renderer2DData m_Renderer2DData; - bool m_WasModified; - - void SendModifiedAnalytics(Analytics.IAnalytics analytics) - { - if (m_WasModified) - { - Analytics.RendererAssetData modifiedData = new Analytics.RendererAssetData(); - modifiedData.instance_id = m_Renderer2DData.GetInstanceID(); - modifiedData.was_create_event = false; - modifiedData.blending_layers_count = 0; - modifiedData.blending_modes_used = 0; - analytics.SendData(Analytics.AnalyticsDataTypes.k_Renderer2DDataString, modifiedData); - } - } - - void OnEnable() - { - m_WasModified = false; - m_Renderer2DData = (Renderer2DData)serializedObject.targetObject; - - m_TransparencySortMode = serializedObject.FindProperty("m_TransparencySortMode"); - m_TransparencySortAxis = serializedObject.FindProperty("m_TransparencySortAxis"); - m_HDREmulationScale = serializedObject.FindProperty("m_HDREmulationScale"); - m_LightBlendStyles = serializedObject.FindProperty("m_LightBlendStyles"); - - int numBlendStyles = m_LightBlendStyles.arraySize; - m_LightBlendStylePropsArray = new LightBlendStyleProps[numBlendStyles]; - - for (int i = 0; i < numBlendStyles; ++i) - { - SerializedProperty blendStyleProp = m_LightBlendStyles.GetArrayElementAtIndex(i); - ref LightBlendStyleProps props = ref m_LightBlendStylePropsArray[i]; - - props.name = blendStyleProp.FindPropertyRelative("name"); - props.maskTextureChannel = blendStyleProp.FindPropertyRelative("maskTextureChannel"); - props.renderTextureScale = blendStyleProp.FindPropertyRelative("renderTextureScale"); - props.blendMode = blendStyleProp.FindPropertyRelative("blendMode"); - props.blendFactorMultiplicative = blendStyleProp.FindPropertyRelative("customBlendFactors.multiplicative"); - props.blendFactorAdditive = blendStyleProp.FindPropertyRelative("customBlendFactors.additive"); - - if (props.blendFactorMultiplicative == null) - props.blendFactorMultiplicative = blendStyleProp.FindPropertyRelative("customBlendFactors.modulate"); - if (props.blendFactorAdditive == null) - props.blendFactorAdditive = blendStyleProp.FindPropertyRelative("customBlendFactors.additve"); - } - - m_UseDepthStencilBuffer = serializedObject.FindProperty("m_UseDepthStencilBuffer"); - m_PostProcessData = serializedObject.FindProperty("m_PostProcessData"); - m_DefaultMaterialType = serializedObject.FindProperty("m_DefaultMaterialType"); - m_DefaultCustomMaterial = serializedObject.FindProperty("m_DefaultCustomMaterial"); - } - - private void OnDestroy() - { - SendModifiedAnalytics(m_Analytics); - } - - public override void OnInspectorGUI() - { - serializedObject.Update(); - - EditorGUI.BeginChangeCheck(); - - - EditorGUILayout.PropertyField(m_TransparencySortMode, Styles.transparencySortMode); - if(m_TransparencySortMode.intValue == (int)TransparencySortMode.CustomAxis) - EditorGUILayout.PropertyField(m_TransparencySortAxis, Styles.transparencySortAxis); - - EditorGUILayout.PropertyField(m_HDREmulationScale, Styles.hdrEmulationScale); - if (EditorGUI.EndChangeCheck() && m_HDREmulationScale.floatValue < 1.0f) - m_HDREmulationScale.floatValue = 1.0f; - - EditorGUILayout.LabelField(Styles.lightBlendStyles); - EditorGUI.indentLevel++; - - EditorGUI.BeginChangeCheck(); - int numBlendStyles = m_LightBlendStyles.arraySize; - for (int i = 0; i < numBlendStyles; ++i) - { - SerializedProperty blendStyleProp = m_LightBlendStyles.GetArrayElementAtIndex(i); - ref LightBlendStyleProps props = ref m_LightBlendStylePropsArray[i]; - - EditorGUILayout.BeginHorizontal(); - blendStyleProp.isExpanded = EditorGUILayout.Foldout(blendStyleProp.isExpanded, props.name.stringValue, true); - EditorGUILayout.EndHorizontal(); - - if (blendStyleProp.isExpanded) - { - EditorGUI.indentLevel++; - - EditorGUILayout.PropertyField(props.name, Styles.name); - EditorGUILayout.PropertyField(props.maskTextureChannel, Styles.maskTextureChannel); - EditorGUILayout.PropertyField(props.renderTextureScale, Styles.renderTextureScale); - EditorGUILayout.PropertyField(props.blendMode, Styles.blendMode); - - if (props.blendMode.intValue == (int)Light2DBlendStyle.BlendMode.Custom) - { - EditorGUILayout.BeginHorizontal(); - - EditorGUI.indentLevel++; - EditorGUILayout.LabelField(Styles.customBlendFactors, GUILayout.MaxWidth(200.0f)); - EditorGUI.indentLevel--; - - int oldIndentLevel = EditorGUI.indentLevel; - EditorGUI.indentLevel = 0; - - EditorGUIUtility.labelWidth = 80.0f; - EditorGUILayout.PropertyField(props.blendFactorMultiplicative, Styles.blendFactorMultiplicative, GUILayout.MinWidth(110.0f)); - - GUILayout.Space(10.0f); - - EditorGUIUtility.labelWidth = 50.0f; - EditorGUILayout.PropertyField(props.blendFactorAdditive, Styles.blendFactorAdditive, GUILayout.MinWidth(90.0f)); - - EditorGUIUtility.labelWidth = 0.0f; - EditorGUI.indentLevel = oldIndentLevel; - EditorGUILayout.EndHorizontal(); - } - - EditorGUI.indentLevel--; - } - } - - - EditorGUI.indentLevel--; - EditorGUILayout.PropertyField(m_UseDepthStencilBuffer, Styles.useDepthStencilBuffer); - EditorGUILayout.PropertyField(m_PostProcessData, Styles.postProcessData); - - EditorGUILayout.PropertyField(m_DefaultMaterialType, Styles.defaultMaterialType); - if(m_DefaultMaterialType.intValue == (int)Renderer2DData.Renderer2DDefaultMaterialType.Custom) - EditorGUILayout.PropertyField(m_DefaultCustomMaterial, Styles.defaultCustomMaterial); - - m_WasModified |= serializedObject.hasModifiedProperties; - serializedObject.ApplyModifiedProperties(); - } - } -} +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + [CustomEditor(typeof(Renderer2DData), true)] + internal class Renderer2DDataEditor : ScriptableRendererDataEditor + { + class Styles + { + public static readonly GUIContent generalHeader = EditorGUIUtility.TrTextContent("General"); + public static readonly GUIContent lightRenderTexturesHeader = EditorGUIUtility.TrTextContent("Light Render Textures"); + public static readonly GUIContent lightBlendStylesHeader = EditorGUIUtility.TrTextContent("Light Blend Styles", "A Light Blend Style is a collection of properties that describe a particular way of applying lighting."); + public static readonly GUIContent postProcessHeader = EditorGUIUtility.TrTextContent("Post-processing"); + + public static readonly GUIContent transparencySortMode = EditorGUIUtility.TrTextContent("Transparency Sort Mode", "Default sorting mode used for transparent objects"); + public static readonly GUIContent transparencySortAxis = EditorGUIUtility.TrTextContent("Transparency Sort Axis", "Axis used for custom axis sorting mode"); + public static readonly GUIContent hdrEmulationScale = EditorGUIUtility.TrTextContent("HDR Emulation Scale", "Describes the scaling used by lighting to remap dynamic range between LDR and HDR"); + public static readonly GUIContent lightRTScale = EditorGUIUtility.TrTextContent("Render Scale", "The resolution of intermediate light render textures, in relation to the screen resolution. 1.0 means full-screen size."); + public static readonly GUIContent maxLightRTCount = EditorGUIUtility.TrTextContent("Max Light Render Textures", "How many intermediate light render textures can be created and utilized concurrently. Higher value usually leads to better performance on mobile hardware at the cost of more memory."); + public static readonly GUIContent maxShadowRTCount = EditorGUIUtility.TrTextContent("Max Shadow Render Textures", "How many intermediate shadow render textures can be created and utilized concurrently. Higher value usually leads to better performance on mobile hardware at the cost of more memory."); + public static readonly GUIContent defaultMaterialType = EditorGUIUtility.TrTextContent("Default Material Type", "Material to use when adding new objects to a scene"); + public static readonly GUIContent defaultCustomMaterial = EditorGUIUtility.TrTextContent("Default Custom Material", "Material to use when adding new objects to a scene"); + + public static readonly GUIContent name = EditorGUIUtility.TrTextContent("Name"); + public static readonly GUIContent maskTextureChannel = EditorGUIUtility.TrTextContent("Mask Texture Channel", "Which channel of the mask texture will affect this Light Blend Style."); + public static readonly GUIContent blendMode = EditorGUIUtility.TrTextContent("Blend Mode", "How the lighting should be blended with the main color of the objects."); + public static readonly GUIContent useDepthStencilBuffer = EditorGUIUtility.TrTextContent("Depth/Stencil Buffer", "Uncheck this when you are certain you don't use any feature that requires the depth/stencil buffer (e.g. Sprite Mask). Not using the depth/stencil buffer may improve performance, especially on mobile platforms."); + public static readonly GUIContent postProcessIncluded = EditorGUIUtility.TrTextContent("Enabled", "Turns post-processing on (check box selected) or off (check box cleared). If you clear this check box, Unity excludes post-processing render Passes, shaders, and textures from the build."); + public static readonly GUIContent postProcessData = EditorGUIUtility.TrTextContent("Data", "The asset containing references to shaders and Textures that the Renderer uses for post-processing."); + + public static readonly GUIContent cameraSortingLayerTextureHeader = EditorGUIUtility.TrTextContent("Camera Sorting Layer Texture", "Layers from back most to selected bounds will be rendered to _CameraSortingLayerTexture"); + public static readonly GUIContent cameraSortingLayerTextureBound = EditorGUIUtility.TrTextContent("Foremost Sorting Layer", "Layers from back most to selected bounds will be rendered to _CameraSortingLayersTexture"); + public static readonly GUIContent cameraSortingLayerDownsampling = EditorGUIUtility.TrTextContent("Downsampling Method", "Method used to copy _CameraSortingLayersTexture"); + } + + struct LightBlendStyleProps + { + public SerializedProperty name; + public SerializedProperty maskTextureChannel; + public SerializedProperty blendMode; + public SerializedProperty blendFactorMultiplicative; + public SerializedProperty blendFactorAdditive; + } + + SerializedProperty m_TransparencySortMode; + SerializedProperty m_TransparencySortAxis; + SerializedProperty m_HDREmulationScale; + SerializedProperty m_LightRenderTextureScale; + SerializedProperty m_LightBlendStyles; + LightBlendStyleProps[] m_LightBlendStylePropsArray; + SerializedProperty m_UseDepthStencilBuffer; + SerializedProperty m_DefaultMaterialType; + SerializedProperty m_DefaultCustomMaterial; + SerializedProperty m_MaxLightRenderTextureCount; + SerializedProperty m_MaxShadowRenderTextureCount; + SerializedProperty m_PostProcessData; + + SerializedProperty m_UseCameraSortingLayersTexture; + SerializedProperty m_CameraSortingLayersTextureBound; + SerializedProperty m_CameraSortingLayerDownsamplingMethod; + + SavedBool m_GeneralFoldout; + SavedBool m_LightRenderTexturesFoldout; + SavedBool m_LightBlendStylesFoldout; + SavedBool m_CameraSortingLayerTextureFoldout; + SavedBool m_PostProcessingFoldout; + + Analytics.Renderer2DAnalytics m_Analytics = Analytics.Renderer2DAnalytics.instance; + Renderer2DData m_Renderer2DData; + bool m_WasModified; + + void SendModifiedAnalytics(Analytics.IAnalytics analytics) + { + if (m_WasModified) + { + Analytics.RendererAssetData modifiedData = new Analytics.RendererAssetData(); + modifiedData.instance_id = m_Renderer2DData.GetInstanceID(); + modifiedData.was_create_event = false; + modifiedData.blending_layers_count = 0; + modifiedData.blending_modes_used = 0; + analytics.SendData(Analytics.AnalyticsDataTypes.k_Renderer2DDataString, modifiedData); + } + } + + void OnEnable() + { + m_WasModified = false; + m_Renderer2DData = (Renderer2DData)serializedObject.targetObject; + + m_TransparencySortMode = serializedObject.FindProperty("m_TransparencySortMode"); + m_TransparencySortAxis = serializedObject.FindProperty("m_TransparencySortAxis"); + m_HDREmulationScale = serializedObject.FindProperty("m_HDREmulationScale"); + m_LightRenderTextureScale = serializedObject.FindProperty("m_LightRenderTextureScale"); + m_LightBlendStyles = serializedObject.FindProperty("m_LightBlendStyles"); + m_MaxLightRenderTextureCount = serializedObject.FindProperty("m_MaxLightRenderTextureCount"); + m_MaxShadowRenderTextureCount = serializedObject.FindProperty("m_MaxShadowRenderTextureCount"); + m_PostProcessData = serializedObject.FindProperty("m_PostProcessData"); + + m_CameraSortingLayersTextureBound = serializedObject.FindProperty("m_CameraSortingLayersTextureBound"); + m_UseCameraSortingLayersTexture = serializedObject.FindProperty("m_UseCameraSortingLayersTexture"); + m_CameraSortingLayerDownsamplingMethod = serializedObject.FindProperty("m_CameraSortingLayerDownsamplingMethod"); + + int numBlendStyles = m_LightBlendStyles.arraySize; + m_LightBlendStylePropsArray = new LightBlendStyleProps[numBlendStyles]; + + for (int i = 0; i < numBlendStyles; ++i) + { + SerializedProperty blendStyleProp = m_LightBlendStyles.GetArrayElementAtIndex(i); + ref LightBlendStyleProps props = ref m_LightBlendStylePropsArray[i]; + + props.name = blendStyleProp.FindPropertyRelative("name"); + props.maskTextureChannel = blendStyleProp.FindPropertyRelative("maskTextureChannel"); + props.blendMode = blendStyleProp.FindPropertyRelative("blendMode"); + props.blendFactorMultiplicative = blendStyleProp.FindPropertyRelative("customBlendFactors.multiplicative"); + props.blendFactorAdditive = blendStyleProp.FindPropertyRelative("customBlendFactors.additive"); + + if (props.blendFactorMultiplicative == null) + props.blendFactorMultiplicative = blendStyleProp.FindPropertyRelative("customBlendFactors.modulate"); + if (props.blendFactorAdditive == null) + props.blendFactorAdditive = blendStyleProp.FindPropertyRelative("customBlendFactors.additve"); + } + + m_UseDepthStencilBuffer = serializedObject.FindProperty("m_UseDepthStencilBuffer"); + m_DefaultMaterialType = serializedObject.FindProperty("m_DefaultMaterialType"); + m_DefaultCustomMaterial = serializedObject.FindProperty("m_DefaultCustomMaterial"); + + m_GeneralFoldout = new SavedBool($"{target.GetType()}.GeneralFoldout", true); + m_LightRenderTexturesFoldout = new SavedBool($"{target.GetType()}.LightRenderTexturesFoldout", true); + m_LightBlendStylesFoldout = new SavedBool($"{target.GetType()}.LightBlendStylesFoldout", true); + m_CameraSortingLayerTextureFoldout = new SavedBool($"{target.GetType()}.CameraSortingLayerTextureFoldout", true); + m_PostProcessingFoldout = new SavedBool($"{target.GetType()}.PostProcessingFoldout", true); + } + + private void OnDestroy() + { + SendModifiedAnalytics(m_Analytics); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + DrawGeneral(); + DrawLightRenderTextures(); + DrawLightBlendStyles(); + DrawCameraSortingLayerTexture(); + DrawPostProcessing(); + + m_WasModified |= serializedObject.hasModifiedProperties; + serializedObject.ApplyModifiedProperties(); + + EditorGUILayout.Space(); + base.OnInspectorGUI(); // Draw the base UI, contains ScriptableRenderFeatures list + } + + public void DrawCameraSortingLayerTexture() + { + CoreEditorUtils.DrawSplitter(); + m_CameraSortingLayerTextureFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.cameraSortingLayerTextureHeader, m_CameraSortingLayerTextureFoldout.value); + if (!m_CameraSortingLayerTextureFoldout.value) + return; + + SortingLayer[] sortingLayers = SortingLayer.layers; + string[] optionNames = new string[sortingLayers.Length + 1]; + int[] optionIds = new int[sortingLayers.Length + 1]; + optionNames[0] = "Disabled"; + optionIds[0] = -1; + + int currentOptionIndex = 0; + for (int i = 0; i < sortingLayers.Length; i++) + { + optionNames[i + 1] = sortingLayers[i].name; + optionIds[i + 1] = sortingLayers[i].id; + if (sortingLayers[i].id == m_CameraSortingLayersTextureBound.intValue) + currentOptionIndex = i + 1; + } + + + int selectedOptionIndex = !m_UseCameraSortingLayersTexture.boolValue ? 0 : currentOptionIndex; + selectedOptionIndex = EditorGUILayout.Popup(Styles.cameraSortingLayerTextureBound, selectedOptionIndex, optionNames); + + m_UseCameraSortingLayersTexture.boolValue = selectedOptionIndex != 0; + m_CameraSortingLayersTextureBound.intValue = optionIds[selectedOptionIndex]; + + EditorGUI.BeginDisabledGroup(!m_UseCameraSortingLayersTexture.boolValue); + EditorGUILayout.PropertyField(m_CameraSortingLayerDownsamplingMethod, Styles.cameraSortingLayerDownsampling); + EditorGUI.EndDisabledGroup(); + } + + private void DrawGeneral() + { + CoreEditorUtils.DrawSplitter(); + m_GeneralFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.generalHeader, m_GeneralFoldout.value); + if (!m_GeneralFoldout.value) + return; + + EditorGUILayout.PropertyField(m_TransparencySortMode, Styles.transparencySortMode); + + using (new EditorGUI.DisabledGroupScope(m_TransparencySortMode.intValue != (int)TransparencySortMode.CustomAxis)) + EditorGUILayout.PropertyField(m_TransparencySortAxis, Styles.transparencySortAxis); + + EditorGUILayout.PropertyField(m_DefaultMaterialType, Styles.defaultMaterialType); + if (m_DefaultMaterialType.intValue == (int)Renderer2DData.Renderer2DDefaultMaterialType.Custom) + EditorGUILayout.PropertyField(m_DefaultCustomMaterial, Styles.defaultCustomMaterial); + + EditorGUILayout.PropertyField(m_UseDepthStencilBuffer, Styles.useDepthStencilBuffer); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_HDREmulationScale, Styles.hdrEmulationScale); + if (EditorGUI.EndChangeCheck() && m_HDREmulationScale.floatValue < 1.0f) + m_HDREmulationScale.floatValue = 1.0f; + + EditorGUILayout.Space(); + } + + private void DrawLightRenderTextures() + { + CoreEditorUtils.DrawSplitter(); + m_LightRenderTexturesFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.lightRenderTexturesHeader, m_LightRenderTexturesFoldout.value); + if (!m_LightRenderTexturesFoldout.value) + return; + + EditorGUILayout.PropertyField(m_LightRenderTextureScale, Styles.lightRTScale); + EditorGUILayout.PropertyField(m_MaxLightRenderTextureCount, Styles.maxLightRTCount); + EditorGUILayout.PropertyField(m_MaxShadowRenderTextureCount, Styles.maxShadowRTCount); + + EditorGUILayout.Space(); + } + + private void DrawLightBlendStyles() + { + CoreEditorUtils.DrawSplitter(); + m_LightBlendStylesFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.lightBlendStylesHeader, m_LightBlendStylesFoldout.value); + if (!m_LightBlendStylesFoldout.value) + return; + + int numBlendStyles = m_LightBlendStyles.arraySize; + for (int i = 0; i < numBlendStyles; ++i) + { + ref LightBlendStyleProps props = ref m_LightBlendStylePropsArray[i]; + + EditorGUILayout.PropertyField(props.name, Styles.name); + EditorGUILayout.PropertyField(props.maskTextureChannel, Styles.maskTextureChannel); + EditorGUILayout.PropertyField(props.blendMode, Styles.blendMode); + + EditorGUILayout.Space(); + EditorGUILayout.Space(); + } + + EditorGUILayout.Space(); + } + + private void DrawPostProcessing() + { + CoreEditorUtils.DrawSplitter(); + m_PostProcessingFoldout.value = CoreEditorUtils.DrawHeaderFoldout(Styles.postProcessHeader, m_PostProcessingFoldout.value); + if (!m_PostProcessingFoldout.value) + return; + + EditorGUI.BeginChangeCheck(); + var postProcessIncluded = EditorGUILayout.Toggle(Styles.postProcessIncluded, m_PostProcessData.objectReferenceValue != null); + if (EditorGUI.EndChangeCheck()) + { + m_PostProcessData.objectReferenceValue = postProcessIncluded ? UnityEngine.Rendering.Universal.PostProcessData.GetDefaultPostProcessData() : null; + } + + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_PostProcessData, Styles.postProcessData); + EditorGUI.indentLevel--; + + EditorGUILayout.Space(); + } + } +} diff --git a/Editor/2D/Renderer2DDataEditor.cs.meta b/Editor/2D/Renderer2DDataEditor.cs.meta index e385e82..2972fec 100644 --- a/Editor/2D/Renderer2DDataEditor.cs.meta +++ b/Editor/2D/Renderer2DDataEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: c2fe41a21634ebe40a7786f6472b3cac -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c2fe41a21634ebe40a7786f6472b3cac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Renderer2DMenus.cs b/Editor/2D/Renderer2DMenus.cs index ae47702..f15f6c1 100644 --- a/Editor/2D/Renderer2DMenus.cs +++ b/Editor/2D/Renderer2DMenus.cs @@ -1,173 +1,196 @@ -using System; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; -using UnityEngine.Rendering.Universal; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEditor.ProjectWindowCallback; -using UnityEngine.Rendering; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - - static class Renderer2DMenus - { - static void Create2DRendererData(Action onCreatedCallback) - { - var instance = ScriptableObject.CreateInstance(); - instance.onCreated += onCreatedCallback; - ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, instance, "New 2D Renderer Data.asset", null, null); - } - - class Create2DRendererDataAsset : EndNameEditAction - { - public event Action onCreated; - - public override void Action(int instanceId, string pathName, string resourceFile) - { - var instance = CreateInstance(); - AssetDatabase.CreateAsset(instance, pathName); - Selection.activeObject = instance; - - onCreated(instance); - } - } - - internal static void PlaceGameObjectInFrontOfSceneView(GameObject go) - { - var sceneViews = SceneView.sceneViews; - if (sceneViews.Count >= 1) - { - SceneView view = SceneView.lastActiveSceneView; - if (!view) - view = sceneViews[0] as SceneView; - - if (view) - view.MoveToView(go.transform); - } - } - - - // This is from GOCreationCommands - internal static void Place(GameObject go, GameObject parent) - { - if (parent != null) - { - var transform = go.transform; - Undo.SetTransformParent(transform, parent.transform, "Reparenting"); - transform.localPosition = Vector3.zero; - transform.localRotation = Quaternion.identity; - transform.localScale = Vector3.one; - go.layer = parent.layer; - - if (parent.GetComponent()) - ObjectFactory.AddComponent(go); - } - else - { - PlaceGameObjectInFrontOfSceneView(go); - StageUtility.PlaceGameObjectInCurrentStage(go); // may change parent - go.transform.position = new Vector3(go.transform.position.x, go.transform.position.y, 0); - } - - // Only at this point do we know the actual parent of the object and can modify its name accordingly. - GameObjectUtility.EnsureUniqueNameForSibling(go); - Undo.SetCurrentGroupName("Create " + go.name); - - //EditorWindow.FocusWindowIfItsOpen(); - Selection.activeGameObject = go; - } - - static void CreateLight(MenuCommand menuCommand, string name, Light2D.LightType type) - { - GameObject go = ObjectFactory.CreateGameObject(name, typeof(Light2D)); - Light2D light2D = go.GetComponent(); - light2D.lightType = type; - - var parent = menuCommand.context as GameObject; - Place(go, parent); - - Analytics.Light2DData lightData = new Analytics.Light2DData(); - lightData.was_create_event = true; - lightData.instance_id = light2D.GetInstanceID(); - lightData.light_type = light2D.lightType; - Analytics.Renderer2DAnalytics.instance.SendData(Analytics.AnalyticsDataTypes.k_LightDataString, lightData); - } - - static bool CreateLightValidation() - { - return Light2DEditorUtility.IsUsing2DRenderer(); - } - - [MenuItem("GameObject/Light/2D/Freeform Light 2D (Experimental)", false, -100)] - static void CreateFreeformLight2D(MenuCommand menuCommand) - { - CreateLight(menuCommand, "Freeform Light 2D", Light2D.LightType.Freeform); - } - - [MenuItem("GameObject/Light/2D/Freeform Light 2D (Experimental)", true, -100)] - static bool CreateFreeformLight2DValidation() - { - return CreateLightValidation(); - } - - [MenuItem("GameObject/Light/2D/Sprite Light 2D (Experimental)", false, -100)] - static void CreateSpriteLight2D(MenuCommand menuCommand) - { - CreateLight(menuCommand, "Sprite Light 2D", Light2D.LightType.Sprite); - } - [MenuItem("GameObject/Light/2D/Sprite Light 2D (Experimental)", true, -100)] - static bool CreateSpriteLight2DValidation() - { - return CreateLightValidation(); - } - - [MenuItem("GameObject/Light/2D/Parametric Light 2D (Experimental)", false, -100)] - static void CreateParametricLight2D(MenuCommand menuCommand) - { - CreateLight(menuCommand, "Parametric Light 2D", Light2D.LightType.Parametric); - } - [MenuItem("GameObject/Light/2D/Parametric Light 2D (Experimental)", true, -100)] - static bool CreateParametricLight2DValidation() - { - return CreateLightValidation(); - } - - [MenuItem("GameObject/Light/2D/Point Light 2D (Experimental)", false, -100)] - static void CreatePointLight2D(MenuCommand menuCommand) - { - CreateLight(menuCommand, "Point Light 2D", Light2D.LightType.Point); - } - - [MenuItem("GameObject/Light/2D/Point Light 2D (Experimental)", true, -100)] - static bool CreatePointLight2DValidation() - { - return CreateLightValidation(); - } - - [MenuItem("GameObject/Light/2D/Global Light 2D (Experimental)", false, -100)] - static void CreateGlobalLight2D(MenuCommand menuCommand) - { - CreateLight(menuCommand, "Global Light 2D", Light2D.LightType.Global); - } - [MenuItem("GameObject/Light/2D/Global Light 2D (Experimental)", true, -100)] - static bool CreateGlobalLight2DValidation() - { - return CreateLightValidation(); - } - - [MenuItem("Assets/Create/Rendering/Universal Render Pipeline/2D Renderer (Experimental)", priority = CoreUtils.assetCreateMenuPriority2 + 1)] - static void Create2DRendererData() - { - Renderer2DMenus.Create2DRendererData((instance) => - { - Analytics.RendererAssetData modifiedData = new Analytics.RendererAssetData(); - modifiedData.instance_id = instance.GetInstanceID(); - modifiedData.was_create_event = true; - modifiedData.blending_layers_count = 1; - modifiedData.blending_modes_used = 2; - Analytics.Renderer2DAnalytics.instance.SendData(Analytics.AnalyticsDataTypes.k_Renderer2DDataString, modifiedData); - }); - } - } -} +using System; +using UnityEditor.ProjectWindowCallback; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.Rendering.Universal; +using UnityEngine.Rendering; + + +namespace UnityEditor.Rendering.Universal +{ + static class Renderer2DMenus + { + static void Create2DRendererData(Action onCreatedCallback) + { + var instance = ScriptableObject.CreateInstance(); + instance.onCreated += onCreatedCallback; + ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, instance, "New 2D Renderer Data.asset", null, null); + } + + class Create2DRendererDataAsset : EndNameEditAction + { + public event Action onCreated; + + public override void Action(int instanceId, string pathName, string resourceFile) + { + var instance = UniversalRenderPipelineAsset.CreateRendererAsset(pathName, RendererType._2DRenderer, false) as Renderer2DData; + Selection.activeObject = instance; + + onCreated?.Invoke(instance); + } + } + + internal static void PlaceGameObjectInFrontOfSceneView(GameObject go) + { + var sceneViews = SceneView.sceneViews; + if (sceneViews.Count >= 1) + { + SceneView view = SceneView.lastActiveSceneView; + if (!view) + view = sceneViews[0] as SceneView; + + if (view) + view.MoveToView(go.transform); + } + } + + // This is from GOCreationCommands + internal static void Place(GameObject go, GameObject parent) + { + if (parent != null) + { + var transform = go.transform; + Undo.SetTransformParent(transform, parent.transform, "Reparenting"); + transform.localPosition = Vector3.zero; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one; + go.layer = parent.layer; + + if (parent.GetComponent()) + ObjectFactory.AddComponent(go); + } + else + { + PlaceGameObjectInFrontOfSceneView(go); + StageUtility.PlaceGameObjectInCurrentStage(go); // may change parent + go.transform.position = new Vector3(go.transform.position.x, go.transform.position.y, 0); + } + + // Only at this point do we know the actual parent of the object and can modify its name accordingly. + GameObjectUtility.EnsureUniqueNameForSibling(go); + Undo.SetCurrentGroupName("Create " + go.name); + + //EditorWindow.FocusWindowIfItsOpen(); + Selection.activeGameObject = go; + } + + static Light2D CreateLight(MenuCommand menuCommand, Light2D.LightType type, Vector3[] shapePath = null) + { + GameObject go = ObjectFactory.CreateGameObject("Light 2D", typeof(Light2D)); + Light2D light2D = go.GetComponent(); + light2D.lightType = type; + + if (shapePath != null && shapePath.Length > 0) + light2D.shapePath = shapePath; + + var parent = menuCommand.context as GameObject; + Place(go, parent); + + Analytics.Light2DData lightData = new Analytics.Light2DData(); + lightData.was_create_event = true; + lightData.instance_id = light2D.GetInstanceID(); + lightData.light_type = light2D.lightType; + Analytics.Renderer2DAnalytics.instance.SendData(Analytics.AnalyticsDataTypes.k_LightDataString, lightData); + + return light2D; + } + + static bool CreateLightValidation() + { + return Light2DEditorUtility.IsUsing2DRenderer(); + } + + [MenuItem("GameObject/Light/Freeform Light 2D/Square", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 4)] + static void CreateSquareFreeformLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Freeform, FreeformPathPresets.CreateSquare()); + } + + [MenuItem("GameObject/Light/Freeform Light 2D/Circle", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 5)] + static void CreateCircleFreeformLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Freeform, FreeformPathPresets.CreateCircle()); + } + + [MenuItem("GameObject/Light/Freeform Light 2D/Isometric Diamond", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 6)] + static void CreateIsometricDiamondFreeformLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Freeform, FreeformPathPresets.CreateIsometricDiamond()); + } + + [MenuItem("GameObject/Light/Freeform Light 2D/Hexagon Flat Top", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 7)] + static void CreateHexagonFlatTopFreeformLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Freeform, FreeformPathPresets.CreateHexagonFlatTop()); + } + + [MenuItem("GameObject/Light/Freeform Light 2D/Hexagon Pointed Top", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 8)] + static void CreateHexagonPointedTopFreeformLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Freeform, FreeformPathPresets.CreateHexagonPointedTop()); + } + + [MenuItem("GameObject/Light/Sprite Light 2D", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 1)] + static void CreateSpriteLight2D(MenuCommand menuCommand) + { + Light2D light = CreateLight(menuCommand, Light2D.LightType.Sprite); + ResourceReloader.ReloadAllNullIn(light, UniversalRenderPipelineAsset.packagePath); + } + + [MenuItem("GameObject/Light/Spot Light 2D", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 2)] + static void CreatePointLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Point); + } + + [MenuItem("GameObject/Light/Global Light 2D", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.gameObjectMenuPriority + 3)] + static void CreateGlobalLight2D(MenuCommand menuCommand) + { + CreateLight(menuCommand, Light2D.LightType.Global); + } + + [MenuItem("GameObject/Light/Freeform Light 2D/Isometric Diamond", true)] + [MenuItem("GameObject/Light/Freeform Light 2D/Square", true)] + [MenuItem("GameObject/Light/Freeform Light 2D/Circle", true)] + [MenuItem("GameObject/Light/Freeform Light 2D/Hexagon Flat Top", true)] + [MenuItem("GameObject/Light/Freeform Light 2D/Hexagon Pointed Top", true)] + [MenuItem("GameObject/Light/Sprite Light 2D", true)] + [MenuItem("GameObject/Light/Spot Light 2D", true)] + [MenuItem("GameObject/Light/Global Light 2D", true)] + static bool CreateLight2DValidation() + { + return CreateLightValidation(); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812")] + internal class CreateUniversalPipelineAsset : EndNameEditAction + { + public override void Action(int instanceId, string pathName, string resourceFile) + { + //Create asset + AssetDatabase.CreateAsset(UniversalRenderPipelineAsset.Create(UniversalRenderPipelineAsset.CreateRendererAsset(pathName, RendererType._2DRenderer)), pathName); + } + } + + [MenuItem("Assets/Create/Rendering/URP Asset (with 2D Renderer)", priority = CoreUtils.Sections.section2 + CoreUtils.Priorities.assetsCreateRenderingMenuPriority)] + static void CreateUniversalPipeline() + { + ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, UniversalRenderPipelineAsset.CreateInstance(), + "New Universal Render Pipeline Asset.asset", null, null); + } + + [MenuItem("Assets/Create/Rendering/URP 2D Renderer", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.assetsCreateRenderingMenuPriority + 1)] + static void Create2DRendererData() + { + Renderer2DMenus.Create2DRendererData((instance) => + { + Analytics.RendererAssetData modifiedData = new Analytics.RendererAssetData(); + modifiedData.instance_id = instance.GetInstanceID(); + modifiedData.was_create_event = true; + modifiedData.blending_layers_count = 1; + modifiedData.blending_modes_used = 2; + Analytics.Renderer2DAnalytics.instance.SendData(Analytics.AnalyticsDataTypes.k_Renderer2DDataString, modifiedData); + }); + } + } +} diff --git a/Editor/2D/Renderer2DMenus.cs.meta b/Editor/2D/Renderer2DMenus.cs.meta index 7c05049..5b8561d 100644 --- a/Editor/2D/Renderer2DMenus.cs.meta +++ b/Editor/2D/Renderer2DMenus.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: dc50d6b320d6d4445898e5f4c7635be2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: dc50d6b320d6d4445898e5f4c7635be2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Renderer2DUpgrader.cs b/Editor/2D/Renderer2DUpgrader.cs deleted file mode 100644 index 7f3472e..0000000 --- a/Editor/2D/Renderer2DUpgrader.cs +++ /dev/null @@ -1,124 +0,0 @@ -using UnityEditor.SceneManagement; -using UnityEngine; -using UnityEngine.Rendering.Universal; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - static class Renderer2DUpgrader - { - delegate void Upgrader(T toUpgrade) where T : Object; - - static void ProcessAssetDatabaseObjects(string searchString, Upgrader upgrader) where T : Object - { - string[] prefabNames = AssetDatabase.FindAssets(searchString); - foreach (string prefabName in prefabNames) - { - string path = AssetDatabase.GUIDToAssetPath(prefabName); - if (path.StartsWith("Assets")) - { - T obj = AssetDatabase.LoadAssetAtPath(path); - if (obj != null) - { - upgrader(obj); - } - } - } - } - - static void UpgradeGameObject(GameObject go) - { - Renderer[] spriteRenderers = go.GetComponentsInChildren(true); - Renderer2DData data = Light2DEditorUtility.GetRenderer2DData(); - if (data != null) - { - Material defaultMat = data.GetDefaultMaterial(DefaultMaterialType.Sprite); - - bool upgraded = false; - foreach (Renderer renderer in spriteRenderers) - { - int materialCount = renderer.sharedMaterials.Length; - Material[] newMaterials = new Material[materialCount]; - - for (int i = 0; i < materialCount; i++) - { - Material mat = renderer.sharedMaterials[i]; - - if (mat != null && mat.shader.name == "Sprites/Default") - { - newMaterials[i] = defaultMat; - upgraded = true; - } - else - { - newMaterials[i] = renderer.sharedMaterials[i]; - } - - } - - if (upgraded) - renderer.sharedMaterials = newMaterials; - } - - if (upgraded) - { - Debug.Log(go.name + " was upgraded.", go); - EditorSceneManager.MarkSceneDirty(go.scene); - } - } - } - - static void UpgradeMaterial(Material mat) - { - Renderer2DData data = Light2DEditorUtility.GetRenderer2DData(); - if (data != null) - { - Material defaultMat = data.GetDefaultMaterial(DefaultMaterialType.Sprite); - - if (mat.shader.name == "Sprites/Default") - { - mat.shader = defaultMat.shader; - } - } - } - - [MenuItem("Edit/Render Pipeline/Universal Render Pipeline/2D Renderer/Upgrade Scene to 2D Renderer (Experimental)", false)] - static void UpgradeSceneTo2DRenderer() - { - if (!EditorUtility.DisplayDialog("2D Renderer Upgrader", "The upgrade will change the material references of Sprite Renderers in currently open scene(s) to a lit material. You can't undo this operation. Make sure you save the scene(s) before proceeding.", "Proceed", "Cancel")) - return; - - GameObject[] gameObjects = Object.FindObjectsOfType(); - if (gameObjects != null && gameObjects.Length > 0) - { - foreach (GameObject go in gameObjects) - { - UpgradeGameObject(go); - } - } - } - - [MenuItem("Edit/Render Pipeline/Universal Render Pipeline/2D Renderer/Upgrade Scene to 2D Renderer (Experimental)", true)] - static bool UpgradeSceneTo2DRendererValidation() - { - return Light2DEditorUtility.IsUsing2DRenderer(); - } - - [MenuItem("Edit/Render Pipeline/Universal Render Pipeline/2D Renderer/Upgrade Project to 2D Renderer (Experimental)", false)] - static void UpgradeProjectTo2DRenderer() - { - if (!EditorUtility.DisplayDialog("2D Renderer Upgrader", "The upgrade will search for all prefabs in your project that use Sprite Renderers and change the material references of those Sprite Renderers to a lit material. You can't undo this operation. It's highly recommended to backup your project before proceeding.", "Proceed", "Cancel")) - return; - - ProcessAssetDatabaseObjects("t: Prefab", UpgradeGameObject); - AssetDatabase.SaveAssets(); - Resources.UnloadUnusedAssets(); - } - - [MenuItem("Edit/Render Pipeline/Universal Render Pipeline/2D Renderer/Upgrade Project to 2D Renderer (Experimental)", true)] - static bool UpgradeProjectTo2DRendererValidation() - { - return Light2DEditorUtility.IsUsing2DRenderer(); - } - } -} diff --git a/Editor/2D/Resources.meta b/Editor/2D/Resources.meta index 6b073b8..23f7cdf 100644 --- a/Editor/2D/Resources.meta +++ b/Editor/2D/Resources.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 95000b81b3fc6af4a916987efa80abbc -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 95000b81b3fc6af4a916987efa80abbc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/Cinemachine.png.meta b/Editor/2D/Resources/Cinemachine.png.meta index a8d1d5f..16502a9 100644 --- a/Editor/2D/Resources/Cinemachine.png.meta +++ b/Editor/2D/Resources/Cinemachine.png.meta @@ -1,115 +1,115 @@ -fileFormatVersion: 2 -guid: ec2f01df0bb1bfe459b5562a9e71c8d4 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 5e97eb03825dee720800000000000000 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ec2f01df0bb1bfe459b5562a9e71c8d4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/InspectorIcons.meta b/Editor/2D/Resources/InspectorIcons.meta index 709f376..8a16c1b 100644 --- a/Editor/2D/Resources/InspectorIcons.meta +++ b/Editor/2D/Resources/InspectorIcons.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 02ab4512457271c48afa84879f6d3848 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 02ab4512457271c48afa84879f6d3848 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/InspectorIcons/FreeformLight.png.meta b/Editor/2D/Resources/InspectorIcons/FreeformLight.png.meta index 0fe678b..7f0f390 100644 --- a/Editor/2D/Resources/InspectorIcons/FreeformLight.png.meta +++ b/Editor/2D/Resources/InspectorIcons/FreeformLight.png.meta @@ -1,104 +1,104 @@ -fileFormatVersion: 2 -guid: 68e5bb6e60bebc046b26d3c3100a523b -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: -1 - nPOTScale: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 68e5bb6e60bebc046b26d3c3100a523b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/InspectorIcons/GlobalLight.png.meta b/Editor/2D/Resources/InspectorIcons/GlobalLight.png.meta index 542417f..457e17b 100644 --- a/Editor/2D/Resources/InspectorIcons/GlobalLight.png.meta +++ b/Editor/2D/Resources/InspectorIcons/GlobalLight.png.meta @@ -1,104 +1,104 @@ -fileFormatVersion: 2 -guid: 8f5dd14b314efbe4684329d8a14bbe38 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: -1 - nPOTScale: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 8f5dd14b314efbe4684329d8a14bbe38 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/InspectorIcons/ParametricLight.png.meta b/Editor/2D/Resources/InspectorIcons/ParametricLight.png.meta index 63a8d18..d2297ed 100644 --- a/Editor/2D/Resources/InspectorIcons/ParametricLight.png.meta +++ b/Editor/2D/Resources/InspectorIcons/ParametricLight.png.meta @@ -1,104 +1,104 @@ -fileFormatVersion: 2 -guid: e957854850ccb7140a538f7a93f8761b -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: -1 - nPOTScale: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e957854850ccb7140a538f7a93f8761b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/InspectorIcons/PointLight.png.meta b/Editor/2D/Resources/InspectorIcons/PointLight.png.meta index 2dd4f27..449aeab 100644 --- a/Editor/2D/Resources/InspectorIcons/PointLight.png.meta +++ b/Editor/2D/Resources/InspectorIcons/PointLight.png.meta @@ -1,104 +1,104 @@ -fileFormatVersion: 2 -guid: b3ab972b21db85d48ade9657efdd4771 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: -1 - nPOTScale: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b3ab972b21db85d48ade9657efdd4771 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/InspectorIcons/SpriteLight.png.meta b/Editor/2D/Resources/InspectorIcons/SpriteLight.png.meta index 0cb6501..2c91e07 100644 --- a/Editor/2D/Resources/InspectorIcons/SpriteLight.png.meta +++ b/Editor/2D/Resources/InspectorIcons/SpriteLight.png.meta @@ -1,104 +1,104 @@ -fileFormatVersion: 2 -guid: 8839c54710da3374f994e12f39b6d65f -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: -1 - nPOTScale: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 8839c54710da3374f994e12f39b6d65f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/LightCapBottomLeft.png.meta b/Editor/2D/Resources/LightCapBottomLeft.png.meta index 606c1fe..0d82e53 100644 --- a/Editor/2D/Resources/LightCapBottomLeft.png.meta +++ b/Editor/2D/Resources/LightCapBottomLeft.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: fb7e2c1cde476854fb7067dcca74511a -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Nintendo Switch - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 935e58b5051eebb458387c2c3bd1e082 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: fb7e2c1cde476854fb7067dcca74511a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Nintendo Switch + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 935e58b5051eebb458387c2c3bd1e082 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/LightCapBottomRight.png.meta b/Editor/2D/Resources/LightCapBottomRight.png.meta index d01e030..031b3aa 100644 --- a/Editor/2D/Resources/LightCapBottomRight.png.meta +++ b/Editor/2D/Resources/LightCapBottomRight.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 108e201829ab4214383a5467adbc0086 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Nintendo Switch - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: ea5038a38b686be48a54da962b177940 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 108e201829ab4214383a5467adbc0086 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Nintendo Switch + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: ea5038a38b686be48a54da962b177940 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/LightCapDown.png.meta b/Editor/2D/Resources/LightCapDown.png.meta index 27c5fab..0e30c34 100644 --- a/Editor/2D/Resources/LightCapDown.png.meta +++ b/Editor/2D/Resources/LightCapDown.png.meta @@ -1,151 +1,151 @@ -fileFormatVersion: 2 -guid: 02232385c7b444348987d74db8dd7b2e -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Nintendo Switch - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 75f594de4db3c3644ad536fd16a13118 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 02232385c7b444348987d74db8dd7b2e +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Nintendo Switch + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 75f594de4db3c3644ad536fd16a13118 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/LightCapTopLeft.png.meta b/Editor/2D/Resources/LightCapTopLeft.png.meta index 853962b..889297e 100644 --- a/Editor/2D/Resources/LightCapTopLeft.png.meta +++ b/Editor/2D/Resources/LightCapTopLeft.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: f4f779c88fa8c514d970afbd68ff6b3f -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Nintendo Switch - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: d444217a2a2ce134fa0126b34043bf4a - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f4f779c88fa8c514d970afbd68ff6b3f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Nintendo Switch + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: d444217a2a2ce134fa0126b34043bf4a + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/LightCapTopRight.png.meta b/Editor/2D/Resources/LightCapTopRight.png.meta index bd3cb47..e9b6d83 100644 --- a/Editor/2D/Resources/LightCapTopRight.png.meta +++ b/Editor/2D/Resources/LightCapTopRight.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: b42c95bdd7efefc43900dbbedc4a39f8 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Nintendo Switch - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: a80a03b4d28bde14c800557718b1b411 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b42c95bdd7efefc43900dbbedc4a39f8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Nintendo Switch + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: a80a03b4d28bde14c800557718b1b411 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/LightCapUp.png.meta b/Editor/2D/Resources/LightCapUp.png.meta index cdb5a9b..620a5cc 100644 --- a/Editor/2D/Resources/LightCapUp.png.meta +++ b/Editor/2D/Resources/LightCapUp.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: a58fea03b14b2be4295b11f21a57a6f7 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 0 - 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: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - - serializedVersion: 3 - buildTarget: Nintendo Switch - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 5943bf8e0c8a40c458cce0f4d2af5f1c - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: a58fea03b14b2be4295b11f21a57a6f7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 0 + 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: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + - serializedVersion: 3 + buildTarget: Nintendo Switch + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 1 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5943bf8e0c8a40c458cce0f4d2af5f1c + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/PixelPerfectCamera.png.meta b/Editor/2D/Resources/PixelPerfectCamera.png.meta index d816f45..36aba83 100644 --- a/Editor/2D/Resources/PixelPerfectCamera.png.meta +++ b/Editor/2D/Resources/PixelPerfectCamera.png.meta @@ -1,103 +1,103 @@ -fileFormatVersion: 2 -guid: 7cba34d70552e144586a4d3ce4a33de5 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 1 - mipBias: -100 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - 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: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 5e97eb03825dee720800000000000000 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 7cba34d70552e144586a4d3ce4a33de5 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/SceneViewIcons.meta b/Editor/2D/Resources/SceneViewIcons.meta index cb2b2c7..39fab08 100644 --- a/Editor/2D/Resources/SceneViewIcons.meta +++ b/Editor/2D/Resources/SceneViewIcons.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: e5f7648dfb00c83428a633efe7759b19 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e5f7648dfb00c83428a633efe7759b19 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/SceneViewIcons/FreeformLight.png.meta b/Editor/2D/Resources/SceneViewIcons/FreeformLight.png.meta index d85a416..4ed67f3 100644 --- a/Editor/2D/Resources/SceneViewIcons/FreeformLight.png.meta +++ b/Editor/2D/Resources/SceneViewIcons/FreeformLight.png.meta @@ -1,91 +1,91 @@ -fileFormatVersion: 2 -guid: c89564426827c76479d8772adb43e6e4 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c89564426827c76479d8772adb43e6e4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/SceneViewIcons/GlobalLight.png.meta b/Editor/2D/Resources/SceneViewIcons/GlobalLight.png.meta index 27ec034..72cc43d 100644 --- a/Editor/2D/Resources/SceneViewIcons/GlobalLight.png.meta +++ b/Editor/2D/Resources/SceneViewIcons/GlobalLight.png.meta @@ -1,91 +1,91 @@ -fileFormatVersion: 2 -guid: 7f923c32ff8dfab40b5673135ddb6cd4 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 7f923c32ff8dfab40b5673135ddb6cd4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/SceneViewIcons/ParametricLight.png.meta b/Editor/2D/Resources/SceneViewIcons/ParametricLight.png.meta index 2db36ef..dc077e5 100644 --- a/Editor/2D/Resources/SceneViewIcons/ParametricLight.png.meta +++ b/Editor/2D/Resources/SceneViewIcons/ParametricLight.png.meta @@ -1,91 +1,91 @@ -fileFormatVersion: 2 -guid: 302e68dd45b9b2d4194ff0f7f454436f -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 302e68dd45b9b2d4194ff0f7f454436f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/SceneViewIcons/PointLight.png.meta b/Editor/2D/Resources/SceneViewIcons/PointLight.png.meta index 05ff668..62949bc 100644 --- a/Editor/2D/Resources/SceneViewIcons/PointLight.png.meta +++ b/Editor/2D/Resources/SceneViewIcons/PointLight.png.meta @@ -1,91 +1,91 @@ -fileFormatVersion: 2 -guid: e1feb27120f96ae4ea48e922cbfd93da -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e1feb27120f96ae4ea48e922cbfd93da +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/SceneViewIcons/SpriteLight.png.meta b/Editor/2D/Resources/SceneViewIcons/SpriteLight.png.meta index fa39e35..a65ee43 100644 --- a/Editor/2D/Resources/SceneViewIcons/SpriteLight.png.meta +++ b/Editor/2D/Resources/SceneViewIcons/SpriteLight.png.meta @@ -1,91 +1,91 @@ -fileFormatVersion: 2 -guid: 70d16a5f04690d74ab9b1ddcbefd47bb -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 70d16a5f04690d74ab9b1ddcbefd47bb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/Resources/Sparkle.png b/Editor/2D/Resources/Sparkle.png new file mode 100644 index 0000000..a6c4356 Binary files /dev/null and b/Editor/2D/Resources/Sparkle.png differ diff --git a/Editor/2D/Resources/Sparkle.png.meta b/Editor/2D/Resources/Sparkle.png.meta new file mode 100644 index 0000000..4d78d59 --- /dev/null +++ b/Editor/2D/Resources/Sparkle.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 4a0aca3a5f2effb41b43cc0a1661d845 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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 + spriteGenerateDepthMesh: 0 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + shadowShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShaderGraph.meta b/Editor/2D/ShaderGraph.meta new file mode 100644 index 0000000..cba413f --- /dev/null +++ b/Editor/2D/ShaderGraph.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 53926c186e474a85a679dafcc7f45d40 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShaderGraph/AssetCallbacks.meta b/Editor/2D/ShaderGraph/AssetCallbacks.meta new file mode 100644 index 0000000..1ebc7e4 --- /dev/null +++ b/Editor/2D/ShaderGraph/AssetCallbacks.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 702cc9b492bf4f6da778b0f5c996b7ad +timeCreated: 1614049029 \ No newline at end of file diff --git a/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteCustomLitShaderGraph.cs b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteCustomLitShaderGraph.cs new file mode 100644 index 0000000..8422daa --- /dev/null +++ b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteCustomLitShaderGraph.cs @@ -0,0 +1,29 @@ +using System; +using UnityEditor.ShaderGraph; +using UnityEngine.Rendering; + +namespace UnityEditor.Rendering.Universal.ShaderGraph +{ + static class CreateSpriteCustomLitShaderGraph + { + [MenuItem("Assets/Create/Shader Graph/URP/Sprite Custom Lit Shader Graph", priority = CoreUtils.Sections.section1 + CoreUtils.Priorities.assetsCreateShaderMenuPriority)] + public static void CreateSpriteLitGraph() + { + var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget)); + target.TrySetActiveSubTarget(typeof(UniversalSpriteCustomLitSubTarget)); + + var blockDescriptors = new[] + { + BlockFields.VertexDescription.Position, + BlockFields.VertexDescription.Normal, + BlockFields.VertexDescription.Tangent, + BlockFields.SurfaceDescription.BaseColor, + UniversalBlockFields.SurfaceDescription.SpriteMask, + BlockFields.SurfaceDescription.NormalTS, + BlockFields.SurfaceDescription.Alpha, + }; + + GraphUtil.CreateNewGraphWithOutputs(new[] { target }, blockDescriptors); + } + } +} diff --git a/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteCustomLitShaderGraph.cs.meta b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteCustomLitShaderGraph.cs.meta new file mode 100644 index 0000000..f25828a --- /dev/null +++ b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteCustomLitShaderGraph.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a8438a1564134e1fbb2669e697bee11f +timeCreated: 1614570277 \ No newline at end of file diff --git a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs similarity index 68% rename from Editor/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs rename to Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs index e5e8f55..4958f6e 100644 --- a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs +++ b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs @@ -1,28 +1,29 @@ -using System; -using UnityEditor.ShaderGraph; - -namespace UnityEditor.Rendering.Universal.ShaderGraph -{ - static class CreateSpriteLitShaderGraph - { - [MenuItem("Assets/Create/Shader/Universal Render Pipeline/Sprite Lit Shader Graph", false, 300)] - public static void CreateSpriteLitGraph() - { - var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget)); - target.TrySetActiveSubTarget(typeof(UniversalSpriteLitSubTarget)); - - var blockDescriptors = new [] - { - BlockFields.VertexDescription.Position, - BlockFields.VertexDescription.Normal, - BlockFields.VertexDescription.Tangent, - BlockFields.SurfaceDescription.BaseColor, - UniversalBlockFields.SurfaceDescription.SpriteMask, - BlockFields.SurfaceDescription.NormalTS, - BlockFields.SurfaceDescription.Alpha, - }; - - GraphUtil.CreateNewGraphWithOutputs(new [] {target}, blockDescriptors); - } - } -} +using System; +using UnityEditor.ShaderGraph; +using UnityEngine.Rendering; + +namespace UnityEditor.Rendering.Universal.ShaderGraph +{ + static class CreateSpriteLitShaderGraph + { + [MenuItem("Assets/Create/Shader Graph/URP/Sprite Lit Shader Graph", priority = CoreUtils.Sections.section1 + CoreUtils.Priorities.assetsCreateShaderMenuPriority + 1)] + public static void CreateSpriteLitGraph() + { + var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget)); + target.TrySetActiveSubTarget(typeof(UniversalSpriteLitSubTarget)); + + var blockDescriptors = new[] + { + BlockFields.VertexDescription.Position, + BlockFields.VertexDescription.Normal, + BlockFields.VertexDescription.Tangent, + BlockFields.SurfaceDescription.BaseColor, + UniversalBlockFields.SurfaceDescription.SpriteMask, + BlockFields.SurfaceDescription.NormalTS, + BlockFields.SurfaceDescription.Alpha, + }; + + GraphUtil.CreateNewGraphWithOutputs(new[] { target }, blockDescriptors); + } + } +} diff --git a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs.meta b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs.meta similarity index 95% rename from Editor/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs.meta rename to Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs.meta index fe91d49..a63a55b 100644 --- a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs.meta +++ b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteLitShaderGraph.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: dc7283e53c0339a40adca7609d7985d7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: dc7283e53c0339a40adca7609d7985d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs similarity index 65% rename from Editor/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs rename to Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs index 03b834d..26c6f17 100644 --- a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs +++ b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs @@ -1,26 +1,27 @@ -using System; -using UnityEditor.ShaderGraph; - -namespace UnityEditor.Rendering.Universal.ShaderGraph -{ - static class CreateSpriteUnlitShaderGraph - { - [MenuItem("Assets/Create/Shader/Universal Render Pipeline/Sprite Unlit Shader Graph", false, 300)] - public static void CreateSpriteUnlitGraph() - { - var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget)); - target.TrySetActiveSubTarget(typeof(UniversalSpriteUnlitSubTarget)); - - var blockDescriptors = new [] - { - BlockFields.VertexDescription.Position, - BlockFields.VertexDescription.Normal, - BlockFields.VertexDescription.Tangent, - BlockFields.SurfaceDescription.BaseColor, - BlockFields.SurfaceDescription.Alpha, - }; - - GraphUtil.CreateNewGraphWithOutputs(new [] {target}, blockDescriptors); - } - } -} +using System; +using UnityEditor.ShaderGraph; +using UnityEngine.Rendering; + +namespace UnityEditor.Rendering.Universal.ShaderGraph +{ + static class CreateSpriteUnlitShaderGraph + { + [MenuItem("Assets/Create/Shader Graph/URP/Sprite Unlit Shader Graph", priority = CoreUtils.Sections.section1 + CoreUtils.Priorities.assetsCreateShaderMenuPriority)] + public static void CreateSpriteUnlitGraph() + { + var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget)); + target.TrySetActiveSubTarget(typeof(UniversalSpriteUnlitSubTarget)); + + var blockDescriptors = new[] + { + BlockFields.VertexDescription.Position, + BlockFields.VertexDescription.Normal, + BlockFields.VertexDescription.Tangent, + BlockFields.SurfaceDescription.BaseColor, + BlockFields.SurfaceDescription.Alpha, + }; + + GraphUtil.CreateNewGraphWithOutputs(new[] { target }, blockDescriptors); + } + } +} diff --git a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs.meta b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs.meta similarity index 95% rename from Editor/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs.meta rename to Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs.meta index b3a8a53..7f3a72c 100644 --- a/Editor/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs.meta +++ b/Editor/2D/ShaderGraph/AssetCallbacks/CreateSpriteUnlitShaderGraph.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: b1d9d11b6a33b4b4e83c36bd926bbb77 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b1d9d11b6a33b4b4e83c36bd926bbb77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShaderGraph/Includes.meta b/Editor/2D/ShaderGraph/Includes.meta new file mode 100644 index 0000000..7147d23 --- /dev/null +++ b/Editor/2D/ShaderGraph/Includes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b0e1457667cf4865bf50a0f8567c4d29 +timeCreated: 1614049038 \ No newline at end of file diff --git a/Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl b/Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl similarity index 50% rename from Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl rename to Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl index 86609cd..b775c7a 100644 --- a/Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl +++ b/Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl @@ -1,26 +1,45 @@ -PackedVaryings vert(Attributes input) -{ - Varyings output = (Varyings)0; - output = BuildVaryings(input); - PackedVaryings packedOutput = PackVaryings(output); - return packedOutput; -} - -half4 frag(PackedVaryings packedInput) : SV_TARGET -{ - Varyings unpacked = UnpackVaryings(packedInput); - UNITY_SETUP_INSTANCE_ID(unpacked); - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); - - SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); - SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); - -#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS - half4 color = surfaceDescription.SpriteColor; -#else - half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); -#endif - - color *= unpacked.color; - return color; -} + +#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SurfaceData2D.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging2D.hlsl" + +PackedVaryings vert(Attributes input) +{ + Varyings output = (Varyings)0; + output = BuildVaryings(input); + PackedVaryings packedOutput = PackVaryings(output); + return packedOutput; +} + +half4 frag(PackedVaryings packedInput) : SV_TARGET +{ + Varyings unpacked = UnpackVaryings(packedInput); + UNITY_SETUP_INSTANCE_ID(unpacked); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); + + SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); + SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); + +#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS + half4 color = surfaceDescription.SpriteColor; +#else + half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); +#endif + + #if defined(DEBUG_DISPLAY) + SurfaceData2D surfaceData; + InitializeSurfaceData(color.rgb, color.a, surfaceData); + InputData2D inputData; + InitializeInputData(unpacked.positionWS.xy, half2(unpacked.texCoord0.xy), inputData); + half4 debugColor = 0; + + SETUP_DEBUG_DATA_2D(inputData, unpacked.positionWS); + + if (CanDebugOverrideOutputColor(surfaceData, inputData, debugColor)) + { + return debugColor; + } + #endif + + color *= unpacked.color; + return color; +} diff --git a/Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl.meta b/Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl.meta similarity index 95% rename from Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl.meta rename to Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl.meta index 529ea1c..35c774c 100644 --- a/Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl.meta +++ b/Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl.meta @@ -1,9 +1,9 @@ -fileFormatVersion: 2 -guid: 4ad8b54817d9f5441910014b5ceb8583 -ShaderImporter: - externalObjects: {} - defaultTextures: [] - nonModifiableTextures: [] - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 4ad8b54817d9f5441910014b5ceb8583 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ShaderGraph/Includes/SpriteLitPass.hlsl b/Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl similarity index 62% rename from Editor/ShaderGraph/Includes/SpriteLitPass.hlsl rename to Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl index ed551c4..da275f1 100644 --- a/Editor/ShaderGraph/Includes/SpriteLitPass.hlsl +++ b/Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl @@ -1,44 +1,55 @@ -#if USE_SHAPE_LIGHT_TYPE_0 -SHAPE_LIGHT(0) -#endif - -#if USE_SHAPE_LIGHT_TYPE_1 -SHAPE_LIGHT(1) -#endif - -#if USE_SHAPE_LIGHT_TYPE_2 -SHAPE_LIGHT(2) -#endif - -#if USE_SHAPE_LIGHT_TYPE_3 -SHAPE_LIGHT(3) -#endif - -#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/CombinedShapeLightShared.hlsl" - -PackedVaryings vert(Attributes input) -{ - Varyings output = (Varyings)0; - output = BuildVaryings(input); - PackedVaryings packedOutput = PackVaryings(output); - return packedOutput; -} - -half4 frag(PackedVaryings packedInput) : SV_TARGET -{ - Varyings unpacked = UnpackVaryings(packedInput); - UNITY_SETUP_INSTANCE_ID(unpacked); - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); - - SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); - SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); - -#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS - half4 color = surfaceDescription.SpriteColor; -#else - half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); -#endif - - color *= unpacked.color; - return CombinedShapeLightShared(color, surfaceDescription.SpriteMask, unpacked.screenPosition.xy / unpacked.screenPosition.w); -} + +#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SurfaceData2D.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging2D.hlsl" + +#if USE_SHAPE_LIGHT_TYPE_0 +SHAPE_LIGHT(0) +#endif + +#if USE_SHAPE_LIGHT_TYPE_1 +SHAPE_LIGHT(1) +#endif + +#if USE_SHAPE_LIGHT_TYPE_2 +SHAPE_LIGHT(2) +#endif + +#if USE_SHAPE_LIGHT_TYPE_3 +SHAPE_LIGHT(3) +#endif + +#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/CombinedShapeLightShared.hlsl" + +PackedVaryings vert(Attributes input) +{ + Varyings output = (Varyings)0; + output = BuildVaryings(input); + PackedVaryings packedOutput = PackVaryings(output); + return packedOutput; +} + +half4 frag(PackedVaryings packedInput) : SV_TARGET +{ + Varyings unpacked = UnpackVaryings(packedInput); + UNITY_SETUP_INSTANCE_ID(unpacked); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); + + SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); + SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); + +#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS + half4 color = surfaceDescription.SpriteColor; +#else + half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); +#endif + + color *= unpacked.color; + + SurfaceData2D surfaceData; + InitializeSurfaceData(color.rgb, color.a, surfaceDescription.SpriteMask, surfaceData); + InputData2D inputData; + InitializeInputData(unpacked.texCoord0.xy, half2(unpacked.screenPosition.xy / unpacked.screenPosition.w), inputData); + SETUP_DEBUG_DATA_2D(inputData, unpacked.positionWS); + + return CombinedShapeLightShared(surfaceData, inputData); +} diff --git a/Editor/ShaderGraph/Includes/SpriteLitPass.hlsl.meta b/Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl.meta similarity index 95% rename from Editor/ShaderGraph/Includes/SpriteLitPass.hlsl.meta rename to Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl.meta index 347acfb..11b24be 100644 --- a/Editor/ShaderGraph/Includes/SpriteLitPass.hlsl.meta +++ b/Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl.meta @@ -1,9 +1,9 @@ -fileFormatVersion: 2 -guid: 3ce18356597793947bd0f671f7363559 -ShaderImporter: - externalObjects: {} - defaultTextures: [] - nonModifiableTextures: [] - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 3ce18356597793947bd0f671f7363559 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl b/Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl similarity index 84% rename from Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl rename to Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl index dbc8868..7284f26 100644 --- a/Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl +++ b/Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl @@ -1,28 +1,29 @@ -PackedVaryings vert(Attributes input) -{ - Varyings output = (Varyings)0; - output = BuildVaryings(input); - PackedVaryings packedOutput = PackVaryings(output); - return packedOutput; -} - -half4 frag(PackedVaryings packedInput) : SV_TARGET -{ - Varyings unpacked = UnpackVaryings(packedInput); - UNITY_SETUP_INSTANCE_ID(unpacked); - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); - - SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); - SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); - - half crossSign = (unpacked.tangentWS.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale(); - half3 bitangent = crossSign * cross(unpacked.normalWS.xyz, unpacked.tangentWS.xyz); - -#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS - half4 color = surfaceDescription.SpriteColor; -#else - half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); -#endif - - return NormalsRenderingShared(color, surfaceDescription.NormalTS, unpacked.tangentWS.xyz, bitangent, unpacked.normalWS); -} +PackedVaryings vert(Attributes input) +{ + Varyings output = (Varyings)0; + output = BuildVaryings(input); + output.normalWS = -GetViewForwardDir(); + PackedVaryings packedOutput = PackVaryings(output); + return packedOutput; +} + +half4 frag(PackedVaryings packedInput) : SV_TARGET +{ + Varyings unpacked = UnpackVaryings(packedInput); + UNITY_SETUP_INSTANCE_ID(unpacked); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); + + SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); + SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); + + half crossSign = (unpacked.tangentWS.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale(); + half3 bitangent = crossSign * cross(unpacked.normalWS.xyz, unpacked.tangentWS.xyz); + +#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS + half4 color = surfaceDescription.SpriteColor; +#else + half4 color = half4(1.0,1.0,1.0, surfaceDescription.Alpha); +#endif + + return NormalsRenderingShared(color, surfaceDescription.NormalTS, unpacked.tangentWS.xyz, bitangent, unpacked.normalWS); +} diff --git a/Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl.meta b/Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl.meta similarity index 95% rename from Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl.meta rename to Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl.meta index 6e7eba1..c67e264 100644 --- a/Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl.meta +++ b/Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl.meta @@ -1,9 +1,9 @@ -fileFormatVersion: 2 -guid: 39ce338156d9f6b40b4702eb2d26d40d -ShaderImporter: - externalObjects: {} - defaultTextures: [] - nonModifiableTextures: [] - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 39ce338156d9f6b40b4702eb2d26d40d +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl b/Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl similarity index 53% rename from Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl rename to Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl index 26bb9c8..21a1f47 100644 --- a/Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl +++ b/Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl @@ -1,28 +1,47 @@ -half4 _RendererColor; - -PackedVaryings vert(Attributes input) -{ - Varyings output = (Varyings)0; - output = BuildVaryings(input); - PackedVaryings packedOutput = PackVaryings(output); - return packedOutput; -} - -half4 frag(PackedVaryings packedInput) : SV_TARGET -{ - Varyings unpacked = UnpackVaryings(packedInput); - UNITY_SETUP_INSTANCE_ID(unpacked); - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); - - SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); - SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); - -#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS - half4 color = surfaceDescription.SpriteColor; -#else - half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); -#endif - - color *= unpacked.color * _RendererColor; - return color; -} + +#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SurfaceData2D.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging2D.hlsl" + +half4 _RendererColor; + +PackedVaryings vert(Attributes input) +{ + Varyings output = (Varyings)0; + output = BuildVaryings(input); + PackedVaryings packedOutput = PackVaryings(output); + return packedOutput; +} + +half4 frag(PackedVaryings packedInput) : SV_TARGET +{ + Varyings unpacked = UnpackVaryings(packedInput); + UNITY_SETUP_INSTANCE_ID(unpacked); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); + + SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); + SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); + +#ifdef UNIVERSAL_USELEGACYSPRITEBLOCKS + half4 color = surfaceDescription.SpriteColor; +#else + half4 color = half4(surfaceDescription.BaseColor, surfaceDescription.Alpha); +#endif + + #if defined(DEBUG_DISPLAY) + SurfaceData2D surfaceData; + InitializeSurfaceData(color.rgb, color.a, surfaceData); + InputData2D inputData; + InitializeInputData(unpacked.positionWS.xy, half2(unpacked.texCoord0.xy), inputData); + half4 debugColor = 0; + + SETUP_DEBUG_DATA_2D(inputData, unpacked.positionWS); + + if (CanDebugOverrideOutputColor(surfaceData, inputData, debugColor)) + { + return debugColor; + } + #endif + + color *= unpacked.color * _RendererColor; + return color; +} diff --git a/Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl.meta b/Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl.meta similarity index 95% rename from Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl.meta rename to Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl.meta index f7efd62..79ef38d 100644 --- a/Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl.meta +++ b/Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl.meta @@ -1,9 +1,9 @@ -fileFormatVersion: 2 -guid: 172e304acf14e434e967133e7ee67273 -ShaderImporter: - externalObjects: {} - defaultTextures: [] - nonModifiableTextures: [] - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 172e304acf14e434e967133e7ee67273 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShaderGraph/Nodes.meta b/Editor/2D/ShaderGraph/Nodes.meta new file mode 100644 index 0000000..de8d8af --- /dev/null +++ b/Editor/2D/ShaderGraph/Nodes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f270bf32cbff4c02ae07004a815c5632 +timeCreated: 1614049109 \ No newline at end of file diff --git a/Editor/2D/ShaderGraph/Nodes/LightTextureNode.cs b/Editor/2D/ShaderGraph/Nodes/LightTextureNode.cs new file mode 100644 index 0000000..14197a1 --- /dev/null +++ b/Editor/2D/ShaderGraph/Nodes/LightTextureNode.cs @@ -0,0 +1,76 @@ +using System; +using UnityEditor.Graphing; +using UnityEditor.Rendering.Universal.ShaderGraph; +using UnityEditor.ShaderGraph; +using UnityEditor.ShaderGraph.Drawing.Controls; +using UnityEditor.ShaderGraph.Internal; +using UnityEngine; + +namespace UnityEngine.Experimental.Rendering.Universal +{ + enum BlendStyle + { + LightTex0, + LightTex1, + LightTex2, + LightTex3, + } + + [Title("Input", "2D", "Light Texture")] + [SubTargetFilterAttribute(new[] { typeof(UniversalSpriteCustomLitSubTarget) })] + class LightTextureNode : AbstractMaterialNode + { + private const int OutputSlotId = 0; + private const string kOutputSlotName = "Out"; + + [SerializeField] private BlendStyle m_BlendStyle = BlendStyle.LightTex0; + + [EnumControl("")] + public BlendStyle blendStyle + { + get { return m_BlendStyle; } + set + { + if (m_BlendStyle == value) + return; + + m_BlendStyle = value; + Dirty(ModificationScope.Graph); + } + } + + public LightTextureNode() + { + name = "2D Light Texture"; + UpdateNodeAfterDeserialization(); + } + + public sealed override void UpdateNodeAfterDeserialization() + { + AddSlot(new Texture2DMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output)); + RemoveSlotsNameNotMatching(new[] { OutputSlotId }); + } + + string GetVariableName() + { + return $"_ShapeLightTexture{(int)m_BlendStyle}"; + } + + public override string GetVariableNameForSlot(int slotId) + { + return $"UnityBuildTexture2DStructNoScale({GetVariableName()})"; + } + + public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode) + { + properties.AddShaderProperty(new Texture2DShaderProperty() + { + overrideReferenceName = GetVariableName(), + generatePropertyBlock = false, + defaultType = Texture2DShaderProperty.DefaultType.White, + // value = m_Texture, + modifiable = false + }); + } + } +} diff --git a/Editor/2D/ShaderGraph/Nodes/LightTextureNode.cs.meta b/Editor/2D/ShaderGraph/Nodes/LightTextureNode.cs.meta new file mode 100644 index 0000000..57ddfea --- /dev/null +++ b/Editor/2D/ShaderGraph/Nodes/LightTextureNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e9aa28223a914899adffca20c1ff4226 +timeCreated: 1612248219 \ No newline at end of file diff --git a/Editor/2D/ShaderGraph/Targets.meta b/Editor/2D/ShaderGraph/Targets.meta new file mode 100644 index 0000000..d7f82d8 --- /dev/null +++ b/Editor/2D/ShaderGraph/Targets.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6235450d5ad64142aeb12e4f3cac5f72 +timeCreated: 1614049047 \ No newline at end of file diff --git a/Editor/2D/ShaderGraph/Targets/UniversalSpriteCustomLitSubTarget.cs b/Editor/2D/ShaderGraph/Targets/UniversalSpriteCustomLitSubTarget.cs new file mode 100644 index 0000000..bfd9a0d --- /dev/null +++ b/Editor/2D/ShaderGraph/Targets/UniversalSpriteCustomLitSubTarget.cs @@ -0,0 +1,309 @@ +using System; +using System.Linq; +using UnityEditor.ShaderGraph; +using UnityEditor.UIElements; + +namespace UnityEditor.Rendering.Universal.ShaderGraph +{ + sealed class UniversalSpriteCustomLitSubTarget : SubTarget + { + static readonly GUID kSourceCodeGuid = new GUID("69e608b3e7e0405bbc2f259ad9cfa196"); // UniversalUnlitSubTarget.cs + + public UniversalSpriteCustomLitSubTarget() + { + displayName = "Sprite Custom Lit"; + } + + public override bool IsActive() => true; + + public override void Setup(ref TargetSetupContext context) + { + context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); + context.AddSubShader(SubShaders.SpriteLit(target)); + } + + public override void GetFields(ref TargetFieldContext context) + { + // Only support SpriteColor legacy block if BaseColor/Alpha are not active + var descs = context.blocks.Select(x => x.descriptor); + bool useLegacyBlocks = !descs.Contains(BlockFields.SurfaceDescription.BaseColor) && !descs.Contains(BlockFields.SurfaceDescription.Alpha); + context.AddField(CoreFields.UseLegacySpriteBlocks, useLegacyBlocks); + + // Surface Type + context.AddField(UniversalFields.SurfaceTransparent); + context.AddField(Fields.DoubleSided); + + // Blend Mode + switch (target.alphaMode) + { + case AlphaMode.Premultiply: + context.AddField(UniversalFields.BlendPremultiply); + break; + case AlphaMode.Additive: + context.AddField(UniversalFields.BlendAdd); + break; + case AlphaMode.Multiply: + context.AddField(UniversalFields.BlendMultiply); + break; + default: + context.AddField(Fields.BlendAlpha); + break; + } + } + + public override void GetActiveBlocks(ref TargetActiveBlockContext context) + { + // Only support SpriteColor legacy block if BaseColor/Alpha are not active + bool useLegacyBlocks = !context.currentBlocks.Contains(BlockFields.SurfaceDescription.BaseColor) && !context.currentBlocks.Contains(BlockFields.SurfaceDescription.Alpha); + context.AddBlock(BlockFields.SurfaceDescriptionLegacy.SpriteColor, useLegacyBlocks); + + context.AddBlock(UniversalBlockFields.SurfaceDescription.SpriteMask); + context.AddBlock(BlockFields.SurfaceDescription.NormalTS); + context.AddBlock(BlockFields.SurfaceDescription.Alpha); + } + + public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) + { + context.AddProperty("Blending Mode", new EnumField(AlphaMode.Alpha) { value = target.alphaMode }, (evt) => + { + if (Equals(target.alphaMode, evt.newValue)) + return; + + registerUndo("Change Blend"); + target.alphaMode = (AlphaMode)evt.newValue; + onChange(); + }); + } + + #region SubShader + static class SubShaders + { + public static SubShaderDescriptor SpriteLit(UniversalTarget target) + { + SubShaderDescriptor result = new SubShaderDescriptor() + { + pipelineTag = UniversalTarget.kPipelineTag, + customTags = UniversalTarget.kLitMaterialTypeTag, + renderType = $"{RenderType.Transparent}", + renderQueue = $"{UnityEditor.ShaderGraph.RenderQueue.Transparent}", + generatesPreview = true, + passes = new PassCollection + { + { SpriteLitPasses.Lit }, + { SpriteLitPasses.Normal }, + // Currently neither of these passes (selection/picking) can be last for the game view for + // UI shaders to render correctly. Verify [1352225] before changing this order. + { CorePasses._2DSceneSelection(target) }, + { CorePasses._2DScenePicking(target) }, + { SpriteLitPasses.Forward }, + }, + }; + return result; + } + } + #endregion + + #region Passes + static class SpriteLitPasses + { + public static PassDescriptor Lit = new PassDescriptor + { + // Definition + displayName = "Sprite Lit", + referenceName = "SHADERPASS_SPRITELIT", + lightMode = "Universal2D", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteLitBlockMasks.FragmentLit, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteLitRequiredFields.Lit, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + keywords = SpriteLitKeywords.Lit, + includes = SpriteLitIncludes.Lit, + }; + + public static PassDescriptor Normal = new PassDescriptor + { + // Definition + displayName = "Sprite Normal", + referenceName = "SHADERPASS_SPRITENORMAL", + lightMode = "NormalsRendering", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteLitBlockMasks.FragmentNormal, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteLitRequiredFields.Normal, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + includes = SpriteLitIncludes.Normal, + }; + + public static PassDescriptor Forward = new PassDescriptor + { + // Definition + displayName = "Sprite Forward", + referenceName = "SHADERPASS_SPRITEFORWARD", + lightMode = "UniversalForward", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteLitBlockMasks.FragmentForward, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteLitRequiredFields.Forward, + keywords = SpriteLitKeywords.Forward, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + includes = SpriteLitIncludes.Forward, + + // Custom Interpolator Support + customInterpolators = CoreCustomInterpDescriptors.Common + }; + } + #endregion + + #region PortMasks + static class SpriteLitBlockMasks + { + public static BlockFieldDescriptor[] FragmentLit = new BlockFieldDescriptor[] + { + BlockFields.SurfaceDescription.BaseColor, + BlockFields.SurfaceDescriptionLegacy.SpriteColor, + BlockFields.SurfaceDescription.Alpha, + UniversalBlockFields.SurfaceDescription.SpriteMask, + }; + + public static BlockFieldDescriptor[] FragmentNormal = new BlockFieldDescriptor[] + { + BlockFields.SurfaceDescription.Alpha, + BlockFields.SurfaceDescription.NormalTS, + }; + + public static BlockFieldDescriptor[] FragmentForward = new BlockFieldDescriptor[] + { + BlockFields.SurfaceDescription.BaseColor, + BlockFields.SurfaceDescriptionLegacy.SpriteColor, + BlockFields.SurfaceDescription.Alpha, + BlockFields.SurfaceDescription.NormalTS, + }; + } + #endregion + + #region RequiredFields + static class SpriteLitRequiredFields + { + public static FieldCollection Lit = new FieldCollection() + { + StructFields.Varyings.color, + StructFields.Varyings.positionWS, + StructFields.Varyings.texCoord0, + StructFields.Varyings.screenPosition, + }; + + public static FieldCollection Normal = new FieldCollection() + { + StructFields.Varyings.normalWS, + StructFields.Varyings.tangentWS, + }; + + public static FieldCollection Forward = new FieldCollection() + { + StructFields.Varyings.color, + StructFields.Varyings.positionWS, + StructFields.Varyings.texCoord0, + }; + } + #endregion + + #region Keywords + static class SpriteLitKeywords + { + public static KeywordCollection Lit = new KeywordCollection + { + { CoreKeywordDescriptors.DebugDisplay }, + }; + + public static KeywordCollection Forward = new KeywordCollection + { + { CoreKeywordDescriptors.DebugDisplay }, + }; + } + #endregion + + #region Includes + static class SpriteLitIncludes + { + const string kSpriteUnlitPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl"; + const string k2DNormal = "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/NormalsRenderingShared.hlsl"; + const string kSpriteNormalPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl"; + const string kSpriteForwardPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl"; + + public static IncludeCollection Lit = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteUnlitPass, IncludeLocation.Postgraph }, + }; + + public static IncludeCollection Normal = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + { k2DNormal, IncludeLocation.Pregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteNormalPass, IncludeLocation.Postgraph }, + }; + + public static IncludeCollection Forward = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteForwardPass, IncludeLocation.Postgraph }, + }; + } + #endregion + } +} diff --git a/Editor/2D/ShaderGraph/Targets/UniversalSpriteCustomLitSubTarget.cs.meta b/Editor/2D/ShaderGraph/Targets/UniversalSpriteCustomLitSubTarget.cs.meta new file mode 100644 index 0000000..c8ea13d --- /dev/null +++ b/Editor/2D/ShaderGraph/Targets/UniversalSpriteCustomLitSubTarget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1bbf55e7974743d8babdda480740a760 +timeCreated: 1616491424 \ No newline at end of file diff --git a/Editor/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs b/Editor/2D/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs similarity index 74% rename from Editor/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs rename to Editor/2D/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs index 82c8314..213652c 100644 --- a/Editor/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs +++ b/Editor/2D/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs @@ -1,287 +1,337 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEditor.ShaderGraph; -using UnityEngine.Rendering; -using UnityEditor.Experimental.Rendering.Universal; -using UnityEditor.ShaderGraph.Legacy; - -namespace UnityEditor.Rendering.Universal.ShaderGraph -{ - sealed class UniversalSpriteLitSubTarget : SubTarget, ILegacyTarget - { - static readonly GUID kSourceCodeGuid = new GUID("ea1514729d7120344b27dcd67fbf34de"); // UniversalSpriteLitSubTarget.cs - - public UniversalSpriteLitSubTarget() - { - displayName = "Sprite Lit"; - } - - public override bool IsActive() => true; - - public override void Setup(ref TargetSetupContext context) - { - context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); - context.AddSubShader(SubShaders.SpriteLit); - } - - public override void GetFields(ref TargetFieldContext context) - { - // Only support SpriteColor legacy block if BaseColor/Alpha are not active - var descs = context.blocks.Select(x => x.descriptor); - bool useLegacyBlocks = !descs.Contains(BlockFields.SurfaceDescription.BaseColor) && !descs.Contains(BlockFields.SurfaceDescription.Alpha); - context.AddField(CoreFields.UseLegacySpriteBlocks, useLegacyBlocks); - - // Surface Type & Blend Mode - context.AddField(UniversalFields.SurfaceTransparent); - context.AddField(Fields.BlendAlpha); - context.AddField(Fields.DoubleSided); - } - - public override void GetActiveBlocks(ref TargetActiveBlockContext context) - { - // Only support SpriteColor legacy block if BaseColor/Alpha are not active - bool useLegacyBlocks = !context.currentBlocks.Contains(BlockFields.SurfaceDescription.BaseColor) && !context.currentBlocks.Contains(BlockFields.SurfaceDescription.Alpha); - context.AddBlock(BlockFields.SurfaceDescriptionLegacy.SpriteColor, useLegacyBlocks); - - context.AddBlock(UniversalBlockFields.SurfaceDescription.SpriteMask); - context.AddBlock(BlockFields.SurfaceDescription.NormalTS); - context.AddBlock(BlockFields.SurfaceDescription.Alpha); - } - - public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) - { - } - - public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary blockMap) - { - blockMap = null; - if(!(masterNode is SpriteLitMasterNode1 spriteLitMasterNode)) - return false; - - // Set blockmap - blockMap = new Dictionary() - { - { BlockFields.VertexDescription.Position, 9 }, - { BlockFields.VertexDescription.Normal, 10 }, - { BlockFields.VertexDescription.Tangent, 11 }, - { BlockFields.SurfaceDescriptionLegacy.SpriteColor, 0 }, - { UniversalBlockFields.SurfaceDescription.SpriteMask, 1 }, - { BlockFields.SurfaceDescription.NormalTS, 2 }, - }; - - return true; - } - -#region SubShader - static class SubShaders - { - public static SubShaderDescriptor SpriteLit = new SubShaderDescriptor() - { - pipelineTag = UniversalTarget.kPipelineTag, - customTags = UniversalTarget.kLitMaterialTypeTag, - renderType = $"{RenderType.Transparent}", - renderQueue = $"{UnityEditor.ShaderGraph.RenderQueue.Transparent}", - generatesPreview = true, - passes = new PassCollection - { - { SpriteLitPasses.Lit }, - { SpriteLitPasses.Normal }, - { SpriteLitPasses.Forward }, - }, - }; - } -#endregion - -#region Passes - static class SpriteLitPasses - { - public static PassDescriptor Lit = new PassDescriptor - { - // Definition - displayName = "Sprite Lit", - referenceName = "SHADERPASS_SPRITELIT", - lightMode = "Universal2D", - useInPreview = true, - - // Template - passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), - sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), - - // Port Mask - validVertexBlocks = CoreBlockMasks.Vertex, - validPixelBlocks = SpriteLitBlockMasks.FragmentLit, - - // Fields - structs = CoreStructCollections.Default, - requiredFields = SpriteLitRequiredFields.Lit, - fieldDependencies = CoreFieldDependencies.Default, - - // Conditional State - renderStates = CoreRenderStates.Default, - pragmas = CorePragmas._2DDefault, - keywords = SpriteLitKeywords.Lit, - includes = SpriteLitIncludes.Lit, - }; - - public static PassDescriptor Normal = new PassDescriptor - { - // Definition - displayName = "Sprite Normal", - referenceName = "SHADERPASS_SPRITENORMAL", - lightMode = "NormalsRendering", - useInPreview = true, - - // Template - passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), - sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), - - // Port Mask - validVertexBlocks = CoreBlockMasks.Vertex, - validPixelBlocks = SpriteLitBlockMasks.FragmentForwardNormal, - - // Fields - structs = CoreStructCollections.Default, - requiredFields = SpriteLitRequiredFields.Normal, - fieldDependencies = CoreFieldDependencies.Default, - - // Conditional State - renderStates = CoreRenderStates.Default, - pragmas = CorePragmas._2DDefault, - includes = SpriteLitIncludes.Normal, - }; - - public static PassDescriptor Forward = new PassDescriptor - { - // Definition - displayName = "Sprite Forward", - referenceName = "SHADERPASS_SPRITEFORWARD", - lightMode = "UniversalForward", - useInPreview = true, - - // Template - passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), - sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), - - // Port Mask - validVertexBlocks = CoreBlockMasks.Vertex, - validPixelBlocks = SpriteLitBlockMasks.FragmentForwardNormal, - - // Fields - structs = CoreStructCollections.Default, - requiredFields = SpriteLitRequiredFields.Forward, - fieldDependencies = CoreFieldDependencies.Default, - - // Conditional State - renderStates = CoreRenderStates.Default, - pragmas = CorePragmas._2DDefault, - includes = SpriteLitIncludes.Forward, - }; - } -#endregion - -#region PortMasks - static class SpriteLitBlockMasks - { - public static BlockFieldDescriptor[] FragmentLit = new BlockFieldDescriptor[] - { - BlockFields.SurfaceDescription.BaseColor, - BlockFields.SurfaceDescriptionLegacy.SpriteColor, - BlockFields.SurfaceDescription.Alpha, - UniversalBlockFields.SurfaceDescription.SpriteMask, - }; - - public static BlockFieldDescriptor[] FragmentForwardNormal = new BlockFieldDescriptor[] - { - BlockFields.SurfaceDescription.BaseColor, - BlockFields.SurfaceDescriptionLegacy.SpriteColor, - BlockFields.SurfaceDescription.Alpha, - BlockFields.SurfaceDescription.NormalTS, - }; - } -#endregion - -#region RequiredFields - static class SpriteLitRequiredFields - { - public static FieldCollection Lit = new FieldCollection() - { - StructFields.Varyings.color, - StructFields.Varyings.texCoord0, - StructFields.Varyings.screenPosition, - }; - - public static FieldCollection Normal = new FieldCollection() - { - StructFields.Varyings.normalWS, - StructFields.Varyings.tangentWS, - }; - - public static FieldCollection Forward = new FieldCollection() - { - StructFields.Varyings.color, - StructFields.Varyings.texCoord0, - }; - } -#endregion - -#region Keywords - static class SpriteLitKeywords - { - public static KeywordCollection Lit = new KeywordCollection - { - { CoreKeywordDescriptors.ShapeLightType0 }, - { CoreKeywordDescriptors.ShapeLightType1 }, - { CoreKeywordDescriptors.ShapeLightType2 }, - { CoreKeywordDescriptors.ShapeLightType3 }, - }; - } -#endregion - -#region Includes - static class SpriteLitIncludes - { - const string k2DLightingUtil = "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"; - const string k2DNormal = "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/NormalsRenderingShared.hlsl"; - const string kSpriteLitPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SpriteLitPass.hlsl"; - const string kSpriteNormalPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SpriteNormalPass.hlsl"; - const string kSpriteForwardPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SpriteForwardPass.hlsl"; - - public static IncludeCollection Lit = new IncludeCollection - { - // Pre-graph - { CoreIncludes.CorePregraph }, - { CoreIncludes.ShaderGraphPregraph }, - { k2DLightingUtil, IncludeLocation.Pregraph }, - - // Post-graph - { CoreIncludes.CorePostgraph }, - { kSpriteLitPass, IncludeLocation.Postgraph }, - }; - - public static IncludeCollection Normal = new IncludeCollection - { - // Pre-graph - { CoreIncludes.CorePregraph }, - { CoreIncludes.ShaderGraphPregraph }, - { k2DNormal, IncludeLocation.Pregraph }, - - // Post-graph - { CoreIncludes.CorePostgraph }, - { kSpriteNormalPass, IncludeLocation.Postgraph }, - }; - - public static IncludeCollection Forward = new IncludeCollection - { - // Pre-graph - { CoreIncludes.CorePregraph }, - { CoreIncludes.ShaderGraphPregraph }, - - // Post-graph - { CoreIncludes.CorePostgraph }, - { kSpriteForwardPass, IncludeLocation.Postgraph }, - }; - } -#endregion - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEditor.ShaderGraph; +using UnityEditor.ShaderGraph.Legacy; +using UnityEditor.UIElements; + +namespace UnityEditor.Rendering.Universal.ShaderGraph +{ + sealed class UniversalSpriteLitSubTarget : SubTarget, ILegacyTarget + { + static readonly GUID kSourceCodeGuid = new GUID("ea1514729d7120344b27dcd67fbf34de"); // UniversalSpriteLitSubTarget.cs + + public UniversalSpriteLitSubTarget() + { + displayName = "Sprite Lit"; + } + + public override bool IsActive() => true; + + public override void Setup(ref TargetSetupContext context) + { + context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); + context.AddSubShader(SubShaders.SpriteLit(target)); + } + + public override void GetFields(ref TargetFieldContext context) + { + // Only support SpriteColor legacy block if BaseColor/Alpha are not active + var descs = context.blocks.Select(x => x.descriptor); + bool useLegacyBlocks = !descs.Contains(BlockFields.SurfaceDescription.BaseColor) && !descs.Contains(BlockFields.SurfaceDescription.Alpha); + context.AddField(CoreFields.UseLegacySpriteBlocks, useLegacyBlocks); + + // Surface Type + context.AddField(UniversalFields.SurfaceTransparent); + context.AddField(Fields.DoubleSided); + + // Blend Mode + switch (target.alphaMode) + { + case AlphaMode.Premultiply: + context.AddField(UniversalFields.BlendPremultiply); + break; + case AlphaMode.Additive: + context.AddField(UniversalFields.BlendAdd); + break; + case AlphaMode.Multiply: + context.AddField(UniversalFields.BlendMultiply); + break; + default: + context.AddField(Fields.BlendAlpha); + break; + } + } + + public override void GetActiveBlocks(ref TargetActiveBlockContext context) + { + // Only support SpriteColor legacy block if BaseColor/Alpha are not active + bool useLegacyBlocks = !context.currentBlocks.Contains(BlockFields.SurfaceDescription.BaseColor) && !context.currentBlocks.Contains(BlockFields.SurfaceDescription.Alpha); + context.AddBlock(BlockFields.SurfaceDescriptionLegacy.SpriteColor, useLegacyBlocks); + + context.AddBlock(UniversalBlockFields.SurfaceDescription.SpriteMask); + context.AddBlock(BlockFields.SurfaceDescription.NormalTS); + context.AddBlock(BlockFields.SurfaceDescription.Alpha); + } + + public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) + { + context.AddProperty("Blending Mode", new EnumField(AlphaMode.Alpha) { value = target.alphaMode }, (evt) => + { + if (Equals(target.alphaMode, evt.newValue)) + return; + + registerUndo("Change Blend"); + target.alphaMode = (AlphaMode)evt.newValue; + onChange(); + }); + } + + public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary blockMap) + { + blockMap = null; + if (!(masterNode is SpriteLitMasterNode1 spriteLitMasterNode)) + return false; + + // Set blockmap + blockMap = new Dictionary() + { + { BlockFields.VertexDescription.Position, 9 }, + { BlockFields.VertexDescription.Normal, 10 }, + { BlockFields.VertexDescription.Tangent, 11 }, + { BlockFields.SurfaceDescriptionLegacy.SpriteColor, 0 }, + { UniversalBlockFields.SurfaceDescription.SpriteMask, 1 }, + { BlockFields.SurfaceDescription.NormalTS, 2 }, + }; + + return true; + } + + #region SubShader + static class SubShaders + { + public static SubShaderDescriptor SpriteLit(UniversalTarget target) + { + SubShaderDescriptor result = new SubShaderDescriptor() + { + pipelineTag = UniversalTarget.kPipelineTag, + customTags = UniversalTarget.kLitMaterialTypeTag, + renderType = $"{RenderType.Transparent}", + renderQueue = $"{UnityEditor.ShaderGraph.RenderQueue.Transparent}", + generatesPreview = true, + passes = new PassCollection + { + { SpriteLitPasses.Lit }, + { SpriteLitPasses.Normal }, + // Currently neither of these passes (selection/picking) can be last for the game view for + // UI shaders to render correctly. Verify [1352225] before changing this order. + { CorePasses._2DSceneSelection(target) }, + { CorePasses._2DScenePicking(target) }, + { SpriteLitPasses.Forward }, + }, + }; + return result; + } + } + #endregion + + #region Passes + static class SpriteLitPasses + { + public static PassDescriptor Lit = new PassDescriptor + { + // Definition + displayName = "Sprite Lit", + referenceName = "SHADERPASS_SPRITELIT", + lightMode = "Universal2D", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteLitBlockMasks.FragmentLit, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteLitRequiredFields.Lit, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + keywords = SpriteLitKeywords.Lit, + includes = SpriteLitIncludes.Lit, + + // Custom Interpolator Support + customInterpolators = CoreCustomInterpDescriptors.Common + }; + + public static PassDescriptor Normal = new PassDescriptor + { + // Definition + displayName = "Sprite Normal", + referenceName = "SHADERPASS_SPRITENORMAL", + lightMode = "NormalsRendering", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteLitBlockMasks.FragmentForwardNormal, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteLitRequiredFields.Normal, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + includes = SpriteLitIncludes.Normal, + + // Custom Interpolator Support + customInterpolators = CoreCustomInterpDescriptors.Common + }; + + public static PassDescriptor Forward = new PassDescriptor + { + // Definition + displayName = "Sprite Forward", + referenceName = "SHADERPASS_SPRITEFORWARD", + lightMode = "UniversalForward", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteLitBlockMasks.FragmentForwardNormal, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteLitRequiredFields.Forward, + keywords = SpriteLitKeywords.Forward, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + includes = SpriteLitIncludes.Forward, + + // Custom Interpolator Support + customInterpolators = CoreCustomInterpDescriptors.Common + }; + } + #endregion + + #region PortMasks + static class SpriteLitBlockMasks + { + public static BlockFieldDescriptor[] FragmentLit = new BlockFieldDescriptor[] + { + BlockFields.SurfaceDescription.BaseColor, + BlockFields.SurfaceDescriptionLegacy.SpriteColor, + BlockFields.SurfaceDescription.Alpha, + UniversalBlockFields.SurfaceDescription.SpriteMask, + }; + + public static BlockFieldDescriptor[] FragmentForwardNormal = new BlockFieldDescriptor[] + { + BlockFields.SurfaceDescription.BaseColor, + BlockFields.SurfaceDescriptionLegacy.SpriteColor, + BlockFields.SurfaceDescription.Alpha, + BlockFields.SurfaceDescription.NormalTS, + }; + } + #endregion + + #region RequiredFields + static class SpriteLitRequiredFields + { + public static FieldCollection Lit = new FieldCollection() + { + StructFields.Varyings.color, + StructFields.Varyings.positionWS, + StructFields.Varyings.texCoord0, + StructFields.Varyings.screenPosition, + }; + + public static FieldCollection Normal = new FieldCollection() + { + StructFields.Varyings.normalWS, + StructFields.Varyings.tangentWS, + }; + + public static FieldCollection Forward = new FieldCollection() + { + StructFields.Varyings.color, + StructFields.Varyings.positionWS, + StructFields.Varyings.texCoord0, + }; + } + #endregion + + #region Keywords + static class SpriteLitKeywords + { + public static KeywordCollection Lit = new KeywordCollection + { + { CoreKeywordDescriptors.ShapeLightType0 }, + { CoreKeywordDescriptors.ShapeLightType1 }, + { CoreKeywordDescriptors.ShapeLightType2 }, + { CoreKeywordDescriptors.ShapeLightType3 }, + { CoreKeywordDescriptors.DebugDisplay }, + }; + + public static KeywordCollection Forward = new KeywordCollection + { + { CoreKeywordDescriptors.DebugDisplay }, + }; + } + #endregion + + #region Includes + static class SpriteLitIncludes + { + const string k2DLightingUtil = "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"; + const string k2DNormal = "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/NormalsRenderingShared.hlsl"; + const string kSpriteLitPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteLitPass.hlsl"; + const string kSpriteNormalPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteNormalPass.hlsl"; + const string kSpriteForwardPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteForwardPass.hlsl"; + + public static IncludeCollection Lit = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + { k2DLightingUtil, IncludeLocation.Pregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteLitPass, IncludeLocation.Postgraph }, + }; + + public static IncludeCollection Normal = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + { k2DNormal, IncludeLocation.Pregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteNormalPass, IncludeLocation.Postgraph }, + }; + + public static IncludeCollection Forward = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteForwardPass, IncludeLocation.Postgraph }, + }; + } + #endregion + } +} diff --git a/Editor/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs.meta b/Editor/2D/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs.meta similarity index 95% rename from Editor/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs.meta rename to Editor/2D/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs.meta index 3d9e22f..520459a 100644 --- a/Editor/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs.meta +++ b/Editor/2D/ShaderGraph/Targets/UniversalSpriteLitSubTarget.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: ea1514729d7120344b27dcd67fbf34de -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ea1514729d7120344b27dcd67fbf34de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs b/Editor/2D/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs similarity index 53% rename from Editor/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs rename to Editor/2D/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs index 4115153..35a1c81 100644 --- a/Editor/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs +++ b/Editor/2D/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs @@ -1,163 +1,244 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEditor.ShaderGraph; -using UnityEngine.Rendering; -using UnityEditor.Experimental.Rendering.Universal; -using UnityEditor.ShaderGraph.Legacy; - -namespace UnityEditor.Rendering.Universal.ShaderGraph -{ - sealed class UniversalSpriteUnlitSubTarget : SubTarget, ILegacyTarget - { - static readonly GUID kSourceCodeGuid = new GUID("ed7c0aacec26e9646b45c96fb318e5a3"); // UniversalSpriteUnlitSubTarget.cs - - public UniversalSpriteUnlitSubTarget() - { - displayName = "Sprite Unlit"; - } - - public override bool IsActive() => true; - - public override void Setup(ref TargetSetupContext context) - { - context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); - context.AddSubShader(SubShaders.SpriteUnlit); - } - - public override void GetFields(ref TargetFieldContext context) - { - var descs = context.blocks.Select(x => x.descriptor); - // Only support SpriteColor legacy block if BaseColor/Alpha are not active - bool useLegacyBlocks = !descs.Contains(BlockFields.SurfaceDescription.BaseColor) && !descs.Contains(BlockFields.SurfaceDescription.Alpha); - context.AddField(CoreFields.UseLegacySpriteBlocks, useLegacyBlocks); - - // Surface Type & Blend Mode - context.AddField(UniversalFields.SurfaceTransparent); - context.AddField(Fields.BlendAlpha); - context.AddField(Fields.DoubleSided); - } - - public override void GetActiveBlocks(ref TargetActiveBlockContext context) - { - // Only support SpriteColor legacy block if BaseColor/Alpha are not active - bool useLegacyBlocks = !context.currentBlocks.Contains(BlockFields.SurfaceDescription.BaseColor) && !context.currentBlocks.Contains(BlockFields.SurfaceDescription.Alpha); - context.AddBlock(BlockFields.SurfaceDescriptionLegacy.SpriteColor, useLegacyBlocks); - - context.AddBlock(BlockFields.SurfaceDescription.Alpha); - } - - public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) - { - } - - public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary blockMap) - { - blockMap = null; - if(!(masterNode is SpriteUnlitMasterNode1 spriteUnlitMasterNode)) - return false; - - // Set blockmap - blockMap = new Dictionary() - { - { BlockFields.VertexDescription.Position, 9 }, - { BlockFields.VertexDescription.Normal, 10 }, - { BlockFields.VertexDescription.Tangent, 11 }, - { BlockFields.SurfaceDescriptionLegacy.SpriteColor, 0 }, - }; - - return true; - } - -#region SubShader - static class SubShaders - { - public static SubShaderDescriptor SpriteUnlit = new SubShaderDescriptor() - { - pipelineTag = UniversalTarget.kPipelineTag, - customTags = UniversalTarget.kUnlitMaterialTypeTag, - renderType = $"{RenderType.Transparent}", - renderQueue = $"{UnityEditor.ShaderGraph.RenderQueue.Transparent}", - generatesPreview = true, - passes = new PassCollection - { - { SpriteUnlitPasses.Unlit }, - }, - }; - } -#endregion - -#region Passes - static class SpriteUnlitPasses - { - public static PassDescriptor Unlit = new PassDescriptor - { - // Definition - referenceName = "SHADERPASS_SPRITEUNLIT", - useInPreview = true, - - // Template - passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), - sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), - - // Port Mask - validVertexBlocks = CoreBlockMasks.Vertex, - validPixelBlocks = SpriteUnlitBlockMasks.Fragment, - - // Fields - structs = CoreStructCollections.Default, - requiredFields = SpriteUnlitRequiredFields.Unlit, - fieldDependencies = CoreFieldDependencies.Default, - - // Conditional State - renderStates = CoreRenderStates.Default, - pragmas = CorePragmas._2DDefault, - includes = SpriteUnlitIncludes.Unlit, - }; - } -#endregion - -#region PortMasks - static class SpriteUnlitBlockMasks - { - public static BlockFieldDescriptor[] Fragment = new BlockFieldDescriptor[] - { - BlockFields.SurfaceDescription.BaseColor, - BlockFields.SurfaceDescriptionLegacy.SpriteColor, - BlockFields.SurfaceDescription.Alpha, - }; - } -#endregion - -#region RequiredFields - static class SpriteUnlitRequiredFields - { - public static FieldCollection Unlit = new FieldCollection() - { - StructFields.Attributes.color, - StructFields.Attributes.uv0, - StructFields.Varyings.color, - StructFields.Varyings.texCoord0, - }; - } -#endregion - -#region Includes - static class SpriteUnlitIncludes - { - const string kSpriteUnlitPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl"; - - public static IncludeCollection Unlit = new IncludeCollection - { - // Pre-graph - { CoreIncludes.CorePregraph }, - { CoreIncludes.ShaderGraphPregraph }, - - // Post-graph - { CoreIncludes.CorePostgraph }, - { kSpriteUnlitPass, IncludeLocation.Postgraph }, - }; - } -#endregion - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEditor.ShaderGraph; +using UnityEditor.ShaderGraph.Legacy; +using UnityEditor.UIElements; + +namespace UnityEditor.Rendering.Universal.ShaderGraph +{ + sealed class UniversalSpriteUnlitSubTarget : SubTarget, ILegacyTarget + { + static readonly GUID kSourceCodeGuid = new GUID("ed7c0aacec26e9646b45c96fb318e5a3"); // UniversalSpriteUnlitSubTarget.cs + + public UniversalSpriteUnlitSubTarget() + { + displayName = "Sprite Unlit"; + } + + public override bool IsActive() => true; + + public override void Setup(ref TargetSetupContext context) + { + context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); + context.AddSubShader(SubShaders.SpriteUnlit(target)); + } + + public override void GetFields(ref TargetFieldContext context) + { + var descs = context.blocks.Select(x => x.descriptor); + // Only support SpriteColor legacy block if BaseColor/Alpha are not active + bool useLegacyBlocks = !descs.Contains(BlockFields.SurfaceDescription.BaseColor) && !descs.Contains(BlockFields.SurfaceDescription.Alpha); + context.AddField(CoreFields.UseLegacySpriteBlocks, useLegacyBlocks); + + // Surface Type + context.AddField(UniversalFields.SurfaceTransparent); + context.AddField(Fields.DoubleSided); + + // Blend Mode + switch (target.alphaMode) + { + case AlphaMode.Premultiply: + context.AddField(UniversalFields.BlendPremultiply); + break; + case AlphaMode.Additive: + context.AddField(UniversalFields.BlendAdd); + break; + case AlphaMode.Multiply: + context.AddField(UniversalFields.BlendMultiply); + break; + default: + context.AddField(Fields.BlendAlpha); + break; + } + } + + public override void GetActiveBlocks(ref TargetActiveBlockContext context) + { + // Only support SpriteColor legacy block if BaseColor/Alpha are not active + bool useLegacyBlocks = !context.currentBlocks.Contains(BlockFields.SurfaceDescription.BaseColor) && !context.currentBlocks.Contains(BlockFields.SurfaceDescription.Alpha); + context.AddBlock(BlockFields.SurfaceDescriptionLegacy.SpriteColor, useLegacyBlocks); + + context.AddBlock(BlockFields.SurfaceDescription.Alpha); + } + + public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) + { + context.AddProperty("Blending Mode", new EnumField(AlphaMode.Alpha) { value = target.alphaMode }, (evt) => + { + if (Equals(target.alphaMode, evt.newValue)) + return; + + registerUndo("Change Blend"); + target.alphaMode = (AlphaMode)evt.newValue; + onChange(); + }); + } + + public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary blockMap) + { + blockMap = null; + if (!(masterNode is SpriteUnlitMasterNode1 spriteUnlitMasterNode)) + return false; + + // Set blockmap + blockMap = new Dictionary() + { + { BlockFields.VertexDescription.Position, 9 }, + { BlockFields.VertexDescription.Normal, 10 }, + { BlockFields.VertexDescription.Tangent, 11 }, + { BlockFields.SurfaceDescriptionLegacy.SpriteColor, 0 }, + }; + + return true; + } + + #region SubShader + static class SubShaders + { + public static SubShaderDescriptor SpriteUnlit(UniversalTarget target) + { + SubShaderDescriptor result = new SubShaderDescriptor() + { + pipelineTag = UniversalTarget.kPipelineTag, + customTags = UniversalTarget.kUnlitMaterialTypeTag, + renderType = $"{RenderType.Transparent}", + renderQueue = $"{UnityEditor.ShaderGraph.RenderQueue.Transparent}", + generatesPreview = true, + passes = new PassCollection + { + { SpriteUnlitPasses.Unlit }, + // Currently neither of these passes (selection/picking) can be last for the game view for + // UI shaders to render correctly. Verify [1352225] before changing this order. + { CorePasses._2DSceneSelection(target) }, + { CorePasses._2DScenePicking(target) }, + { SpriteUnlitPasses.Forward }, + }, + }; + return result; + } + } + #endregion + + #region Passes + static class SpriteUnlitPasses + { + public static PassDescriptor Unlit = new PassDescriptor + { + // Definition + displayName = "Sprite Unlit", + referenceName = "SHADERPASS_SPRITEUNLIT", + lightMode = "Universal2D", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteUnlitBlockMasks.Fragment, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteUnlitRequiredFields.Unlit, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + keywords = SpriteUnlitKeywords.Unlit, + includes = SpriteUnlitIncludes.Unlit, + + // Custom Interpolator Support + customInterpolators = CoreCustomInterpDescriptors.Common + }; + + public static PassDescriptor Forward = new PassDescriptor + { + // Definition + displayName = "Sprite Unlit", + referenceName = "SHADERPASS_SPRITEFORWARD", + lightMode = "UniversalForward", + useInPreview = true, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = SpriteUnlitBlockMasks.Fragment, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = SpriteUnlitRequiredFields.Unlit, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas._2DDefault, + keywords = SpriteUnlitKeywords.Unlit, + includes = SpriteUnlitIncludes.Unlit, + + // Custom Interpolator Support + customInterpolators = CoreCustomInterpDescriptors.Common + }; + } + #endregion + + #region PortMasks + static class SpriteUnlitBlockMasks + { + public static BlockFieldDescriptor[] Fragment = new BlockFieldDescriptor[] + { + BlockFields.SurfaceDescription.BaseColor, + BlockFields.SurfaceDescriptionLegacy.SpriteColor, + BlockFields.SurfaceDescription.Alpha, + }; + } + #endregion + + #region RequiredFields + static class SpriteUnlitRequiredFields + { + public static FieldCollection Unlit = new FieldCollection() + { + StructFields.Attributes.color, + StructFields.Attributes.uv0, + StructFields.Varyings.positionWS, + StructFields.Varyings.color, + StructFields.Varyings.texCoord0, + }; + } + #endregion + + #region Keywords + static class SpriteUnlitKeywords + { + public static KeywordCollection Unlit = new KeywordCollection + { + { CoreKeywordDescriptors.DebugDisplay }, + }; + } + #endregion + + #region Includes + static class SpriteUnlitIncludes + { + const string kSpriteUnlitPass = "Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/SpriteUnlitPass.hlsl"; + + public static IncludeCollection Unlit = new IncludeCollection + { + // Pre-graph + { CoreIncludes.CorePregraph }, + { CoreIncludes.ShaderGraphPregraph }, + + // Post-graph + { CoreIncludes.CorePostgraph }, + { kSpriteUnlitPass, IncludeLocation.Postgraph }, + }; + } + #endregion + } +} diff --git a/Editor/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs.meta b/Editor/2D/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs.meta similarity index 95% rename from Editor/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs.meta rename to Editor/2D/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs.meta index f0b41e0..8b32783 100644 --- a/Editor/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs.meta +++ b/Editor/2D/ShaderGraph/Targets/UniversalSpriteUnlitSubTarget.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: ed7c0aacec26e9646b45c96fb318e5a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ed7c0aacec26e9646b45c96fb318e5a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShadowCaster2DEditor.cs b/Editor/2D/ShadowCaster2DEditor.cs index cf5bb81..815d202 100644 --- a/Editor/2D/ShadowCaster2DEditor.cs +++ b/Editor/2D/ShadowCaster2DEditor.cs @@ -1,99 +1,142 @@ -using System.Collections; -using System.Collections.Generic; - -using UnityEditor; -using UnityEditor.EditorTools; -using UnityEditor.Experimental.Rendering.Universal.Path2D; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - [CustomEditor(typeof(ShadowCaster2D))] - [CanEditMultipleObjects] - internal class ShadowCaster2DEditor : PathComponentEditor - { - [EditorTool("Edit Shadow Caster Shape", typeof(ShadowCaster2D))] - class ShadowCaster2DShadowCasterShapeTool : ShadowCaster2DShapeTool { }; - - private static class Styles - { - public static GUIContent shadowMode = EditorGUIUtility.TrTextContent("Use Renderer Silhouette", "When this and Self Shadows are enabled, the Renderer's silhouette is considered part of the shadow. When this is enabled and Self Shadows disabled, the Renderer's silhouette is excluded from the shadow."); - public static GUIContent selfShadows = EditorGUIUtility.TrTextContent("Self Shadows", "When enabled, the Renderer casts shadows on itself."); - public static GUIContent castsShadows = EditorGUIUtility.TrTextContent("Casts Shadows", "Specifies if this renderer will cast shadows"); - public static GUIContent sortingLayerPrefixLabel = EditorGUIUtility.TrTextContent("Target Sorting Layers", "Apply shadows to the specified sorting layers."); - } - - SerializedProperty m_HasRenderer; - SerializedProperty m_UseRendererSilhouette; - SerializedProperty m_CastsShadows; - SerializedProperty m_SelfShadows; - SerializedProperty m_ReceivesShadows; - - - SortingLayerDropDown m_SortingLayerDropDown; - - - public void OnEnable() - { - m_UseRendererSilhouette = serializedObject.FindProperty("m_UseRendererSilhouette"); - m_SelfShadows = serializedObject.FindProperty("m_SelfShadows"); - m_CastsShadows = serializedObject.FindProperty("m_CastsShadows"); - m_HasRenderer = serializedObject.FindProperty("m_HasRenderer"); - - m_SortingLayerDropDown = new SortingLayerDropDown(); - m_SortingLayerDropDown.OnEnable(serializedObject, "m_ApplyToSortingLayers"); - } - - public void ShadowCaster2DSceneGUI() - { - ShadowCaster2D shadowCaster = target as ShadowCaster2D; - - Transform t = shadowCaster.transform; - Vector3[] shape = shadowCaster.shapePath; - Handles.color = Color.white; - - for (int i = 0; i < shape.Length - 1; ++i) - { - Handles.DrawAAPolyLine(4, new Vector3[] { t.TransformPoint(shape[i]), t.TransformPoint(shape[i + 1]) }); - } - - if (shape.Length > 1) - Handles.DrawAAPolyLine(4, new Vector3[] { t.TransformPoint(shape[shape.Length - 1]), t.TransformPoint(shape[0]) }); - } - - public void ShadowCaster2DInspectorGUI() where T : ShadowCaster2DShapeTool - { - DoEditButton(PathEditorToolContents.icon, "Edit Shape"); - DoPathInspector(); - DoSnappingInspector(); - } - - - public void OnSceneGUI() - { - if (m_CastsShadows.boolValue) - ShadowCaster2DSceneGUI(); - } - - public override void OnInspectorGUI() - { - serializedObject.Update(); - - using (new EditorGUI.DisabledScope(!m_HasRenderer.boolValue)) // Done to support multiedit - { - EditorGUILayout.PropertyField(m_UseRendererSilhouette, Styles.shadowMode); - } - - EditorGUILayout.PropertyField(m_CastsShadows, Styles.castsShadows); - EditorGUILayout.PropertyField(m_SelfShadows, Styles.selfShadows); - - m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.sortingLayerPrefixLabel, null); - - if (m_CastsShadows.boolValue) - ShadowCaster2DInspectorGUI(); - - serializedObject.ApplyModifiedProperties(); - } - } -} +using UnityEditor.EditorTools; +using UnityEditor.Rendering.Universal.Path2D; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + internal class ShadowCasterPath : ScriptablePath + { + internal Bounds GetBounds() + { + ShadowCaster2D shadowCaster = (ShadowCaster2D)owner; + Renderer m_Renderer = shadowCaster.GetComponent(); + if (m_Renderer != null) + { + return m_Renderer.bounds; + } + else + { + Collider2D collider = shadowCaster.GetComponent(); + if (collider != null) + return collider.bounds; + } + + return new Bounds(shadowCaster.transform.position, shadowCaster.transform.lossyScale); + } + + public override void SetDefaultShape() + { + Clear(); + Bounds bounds = GetBounds(); + + AddPoint(new ControlPoint(bounds.min)); + AddPoint(new ControlPoint(new Vector3(bounds.min.x, bounds.max.y))); + AddPoint(new ControlPoint(bounds.max)); + AddPoint(new ControlPoint(new Vector3(bounds.max.x, bounds.min.y))); + + base.SetDefaultShape(); + } + } + + + [CustomEditor(typeof(ShadowCaster2D))] + [CanEditMultipleObjects] + internal class ShadowCaster2DEditor : PathComponentEditor + { + [EditorTool("Edit Shadow Caster Shape", typeof(ShadowCaster2D))] + class ShadowCaster2DShadowCasterShapeTool : ShadowCaster2DShapeTool { }; + + private static class Styles + { + public static GUIContent shadowMode = EditorGUIUtility.TrTextContent("Use Renderer Silhouette", "When this and Self Shadows are enabled, the Renderer's silhouette is considered part of the shadow. When this is enabled and Self Shadows disabled, the Renderer's silhouette is excluded from the shadow."); + public static GUIContent selfShadows = EditorGUIUtility.TrTextContent("Self Shadows", "When enabled, the Renderer casts shadows on itself."); + public static GUIContent castsShadows = EditorGUIUtility.TrTextContent("Casts Shadows", "Specifies if this renderer will cast shadows"); + public static GUIContent sortingLayerPrefixLabel = EditorGUIUtility.TrTextContent("Target Sorting Layers", "Apply shadows to the specified sorting layers."); + } + + SerializedProperty m_UseRendererSilhouette; + SerializedProperty m_CastsShadows; + SerializedProperty m_SelfShadows; + + + SortingLayerDropDown m_SortingLayerDropDown; + + + public void OnEnable() + { + m_UseRendererSilhouette = serializedObject.FindProperty("m_UseRendererSilhouette"); + m_SelfShadows = serializedObject.FindProperty("m_SelfShadows"); + m_CastsShadows = serializedObject.FindProperty("m_CastsShadows"); + + m_SortingLayerDropDown = new SortingLayerDropDown(); + m_SortingLayerDropDown.OnEnable(serializedObject, "m_ApplyToSortingLayers"); + } + + public void ShadowCaster2DSceneGUI() + { + ShadowCaster2D shadowCaster = target as ShadowCaster2D; + + Transform t = shadowCaster.transform; + Vector3[] shape = shadowCaster.shapePath; + Handles.color = Color.white; + + for (int i = 0; i < shape.Length - 1; ++i) + { + Handles.DrawAAPolyLine(4, new Vector3[] { t.TransformPoint(shape[i]), t.TransformPoint(shape[i + 1]) }); + } + + if (shape.Length > 1) + Handles.DrawAAPolyLine(4, new Vector3[] { t.TransformPoint(shape[shape.Length - 1]), t.TransformPoint(shape[0]) }); + } + + public void ShadowCaster2DInspectorGUI() where T : ShadowCaster2DShapeTool + { + DoEditButton(PathEditorToolContents.icon, "Edit Shape"); + DoPathInspector(); + DoSnappingInspector(); + } + + public void OnSceneGUI() + { + if (m_CastsShadows.boolValue) + ShadowCaster2DSceneGUI(); + } + + public bool HasRenderer() + { + if (targets != null) + { + for (int i = 0; i < targets.Length; i++) + { + ShadowCaster2D shadowCaster = (ShadowCaster2D)targets[i]; + Renderer renderer = shadowCaster.GetComponent(); + if (renderer != null) + return true; + } + } + + return false; + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + using (new EditorGUI.DisabledScope(!HasRenderer())) // Done to support multiedit + { + EditorGUILayout.PropertyField(m_UseRendererSilhouette, Styles.shadowMode); + } + + EditorGUILayout.PropertyField(m_CastsShadows, Styles.castsShadows); + EditorGUILayout.PropertyField(m_SelfShadows, Styles.selfShadows); + + m_SortingLayerDropDown.OnTargetSortingLayers(serializedObject, targets, Styles.sortingLayerPrefixLabel, null); + + if (m_CastsShadows.boolValue) + ShadowCaster2DInspectorGUI(); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Editor/2D/ShadowCaster2DEditor.cs.meta b/Editor/2D/ShadowCaster2DEditor.cs.meta index 655ff5d..fb68a76 100644 --- a/Editor/2D/ShadowCaster2DEditor.cs.meta +++ b/Editor/2D/ShadowCaster2DEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 2cc0da5e119f39940a554dcaeec9f3ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 2cc0da5e119f39940a554dcaeec9f3ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShadowCaster2DShapeTool.cs b/Editor/2D/ShadowCaster2DShapeTool.cs index 9fd0316..40b9025 100644 --- a/Editor/2D/ShadowCaster2DShapeTool.cs +++ b/Editor/2D/ShadowCaster2DShapeTool.cs @@ -1,39 +1,37 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEditor.Experimental.Rendering.Universal.Path2D; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - class ShadowCaster2DShapeTool : PathEditorTool - { - const string k_ShapePath = "m_ShapePath"; - - protected override IShape GetShape(Object target) - { - return (target as ShadowCaster2D).shapePath.ToPolygon(false); - } - - protected override void SetShape(ScriptablePath shapeEditor, SerializedObject serializedObject) - { - serializedObject.Update(); - - var pointsProperty = serializedObject.FindProperty(k_ShapePath); - pointsProperty.arraySize = shapeEditor.pointCount; - - for (var i = 0; i < shapeEditor.pointCount; ++i) - pointsProperty.GetArrayElementAtIndex(i).vector3Value = shapeEditor.GetPoint(i).position; - - // This is untracked right now... - serializedObject.ApplyModifiedProperties(); - - ShadowCaster2D shadowCaster = target as ShadowCaster2D; - if (shadowCaster != null) - { - int hash = LightUtility.GetShapePathHash(shadowCaster.shapePath); - shadowCaster.shapePathHash = hash; - } - } - } -} +using UnityEditor.Rendering.Universal.Path2D; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class ShadowCaster2DShapeTool : PathEditorTool + { + const string k_ShapePath = "m_ShapePath"; + + protected override IShape GetShape(Object target) + { + return (target as ShadowCaster2D).shapePath.ToPolygon(false); + } + + protected override void SetShape(ShadowCasterPath shapeEditor, SerializedObject serializedObject) + { + serializedObject.Update(); + + var pointsProperty = serializedObject.FindProperty(k_ShapePath); + pointsProperty.arraySize = shapeEditor.pointCount; + + for (var i = 0; i < shapeEditor.pointCount; ++i) + pointsProperty.GetArrayElementAtIndex(i).vector3Value = shapeEditor.GetPoint(i).position; + + // This is untracked right now... + serializedObject.ApplyModifiedProperties(); + + ShadowCaster2D shadowCaster = target as ShadowCaster2D; + if (shadowCaster != null) + { + int hash = LightUtility.GetShapePathHash(shadowCaster.shapePath); + shadowCaster.shapePathHash = hash; + } + } + } +} diff --git a/Editor/2D/ShadowCaster2DShapeTool.cs.meta b/Editor/2D/ShadowCaster2DShapeTool.cs.meta index 730a6f2..d08fa02 100644 --- a/Editor/2D/ShadowCaster2DShapeTool.cs.meta +++ b/Editor/2D/ShadowCaster2DShapeTool.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 0d6c3a273fdfa794ea11d8bf9a531114 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 0d6c3a273fdfa794ea11d8bf9a531114 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor.meta b/Editor/2D/ShapeEditor.meta index b7aa454..209117c 100644 --- a/Editor/2D/ShapeEditor.meta +++ b/Editor/2D/ShapeEditor.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 643e7b93cc1f804408a784cc2bc2c1b8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 643e7b93cc1f804408a784cc2bc2c1b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath.meta b/Editor/2D/ShapeEditor/EditablePath.meta index e6a35b1..8247874 100644 --- a/Editor/2D/ShapeEditor/EditablePath.meta +++ b/Editor/2D/ShapeEditor/EditablePath.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 8f29513c816cd7d429633099737385d6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 8f29513c816cd7d429633099737385d6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs b/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs index 321f90e..deef378 100644 --- a/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs +++ b/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs @@ -1,223 +1,223 @@ -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal static class BezierUtility - { - static Vector3[] s_TempPoints = new Vector3[3]; - - public static Vector3 BezierPoint(Vector3 startPosition, Vector3 startTangent, Vector3 endTangent, Vector3 endPosition, float t) - { - float s = 1.0f - t; - return startPosition * s * s * s + startTangent * s * s * t * 3.0f + endTangent * s * t * t * 3.0f + endPosition * t * t * t; - } - - public static Vector3 ClosestPointOnCurve(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, out float t) - { - Vector3 startToEnd = endPosition - startPosition; - Vector3 startToTangent = (startTangent - startPosition); - Vector3 endToTangent = (endTangent - endPosition); - - float sqrError = 0.001f; - - if (Colinear(startToTangent, startToEnd, sqrError) && Colinear(endToTangent, startToEnd, sqrError)) - return ClosestPointToSegment(point, startPosition, endPosition, out t); - - Vector3 leftStartPosition; - Vector3 leftEndPosition; - Vector3 leftStartTangent; - Vector3 leftEndTangent; - - Vector3 rightStartPosition; - Vector3 rightEndPosition; - Vector3 rightStartTangent; - Vector3 rightEndTangent; - - float leftStartT = 0f; - float leftEndT = 0.5f; - float rightStartT = 0.5f; - float rightEndT = 1f; - - SplitBezier(0.5f, startPosition, endPosition, startTangent, endTangent, - out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, - out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); - - Vector3 pointLeft = ClosestPointOnCurveIterative(point, leftStartPosition, leftEndPosition, leftStartTangent, leftEndTangent, sqrError, ref leftStartT, ref leftEndT); - Vector3 pointRight = ClosestPointOnCurveIterative(point, rightStartPosition, rightEndPosition, rightStartTangent, rightEndTangent, sqrError, ref rightStartT, ref rightEndT); - - if ((point - pointLeft).sqrMagnitude < (point - pointRight).sqrMagnitude) - { - t = leftStartT; - return pointLeft; - } - - t = rightStartT; - return pointRight; - } - - public static Vector3 ClosestPointOnCurveFast(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, out float t) - { - float sqrError = 0.001f; - float startT = 0f; - float endT = 1f; - - Vector3 closestPoint = ClosestPointOnCurveIterative(point, startPosition, endPosition, startTangent, endTangent, sqrError, ref startT, ref endT); - - t = startT; - - return closestPoint; - } - - private static Vector3 ClosestPointOnCurveIterative(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, float sqrError, ref float startT, ref float endT) - { - while ((startPosition - endPosition).sqrMagnitude > sqrError) - { - Vector3 startToEnd = endPosition - startPosition; - Vector3 startToTangent = (startTangent - startPosition); - Vector3 endToTangent = (endTangent - endPosition); - - if (Colinear(startToTangent, startToEnd, sqrError) && Colinear(endToTangent, startToEnd, sqrError)) - { - float t; - Vector3 closestPoint = ClosestPointToSegment(point, startPosition, endPosition, out t); - t *= (endT - startT); - startT += t; - endT -= t; - return closestPoint; - } - - Vector3 leftStartPosition; - Vector3 leftEndPosition; - Vector3 leftStartTangent; - Vector3 leftEndTangent; - - Vector3 rightStartPosition; - Vector3 rightEndPosition; - Vector3 rightStartTangent; - Vector3 rightEndTangent; - - SplitBezier(0.5f, startPosition, endPosition, startTangent, endTangent, - out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, - out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); - - s_TempPoints[0] = leftStartPosition; - s_TempPoints[1] = leftStartTangent; - s_TempPoints[2] = leftEndTangent; - - float sqrDistanceLeft = SqrDistanceToPolyLine(point, s_TempPoints); - - s_TempPoints[0] = rightEndPosition; - s_TempPoints[1] = rightEndTangent; - s_TempPoints[2] = rightStartTangent; - - float sqrDistanceRight = SqrDistanceToPolyLine(point, s_TempPoints); - - if (sqrDistanceLeft < sqrDistanceRight) - { - startPosition = leftStartPosition; - endPosition = leftEndPosition; - startTangent = leftStartTangent; - endTangent = leftEndTangent; - - endT -= (endT - startT) * 0.5f; - } - else - { - startPosition = rightStartPosition; - endPosition = rightEndPosition; - startTangent = rightStartTangent; - endTangent = rightEndTangent; - - startT += (endT - startT) * 0.5f; - } - } - - return endPosition; - } - - public static void SplitBezier(float t, Vector3 startPosition, Vector3 endPosition, Vector3 startRightTangent, Vector3 endLeftTangent, - out Vector3 leftStartPosition, out Vector3 leftEndPosition, out Vector3 leftStartTangent, out Vector3 leftEndTangent, - out Vector3 rightStartPosition, out Vector3 rightEndPosition, out Vector3 rightStartTangent, out Vector3 rightEndTangent) - { - Vector3 tangent0 = (startRightTangent - startPosition); - Vector3 tangent1 = (endLeftTangent - endPosition); - Vector3 tangentEdge = (endLeftTangent - startRightTangent); - - Vector3 tangentPoint0 = startPosition + tangent0 * t; - Vector3 tangentPoint1 = endPosition + tangent1 * (1f - t); - Vector3 tangentEdgePoint = startRightTangent + tangentEdge * t; - - Vector3 newTangent0 = tangentPoint0 + (tangentEdgePoint - tangentPoint0) * t; - Vector3 newTangent1 = tangentPoint1 + (tangentEdgePoint - tangentPoint1) * (1f - t); - Vector3 newTangentEdge = newTangent1 - newTangent0; - - Vector3 bezierPoint = newTangent0 + newTangentEdge * t; - - leftStartPosition = startPosition; - leftEndPosition = bezierPoint; - leftStartTangent = tangentPoint0; - leftEndTangent = newTangent0; - - rightStartPosition = bezierPoint; - rightEndPosition = endPosition; - rightStartTangent = newTangent1; - rightEndTangent = tangentPoint1; - } - - private static Vector3 ClosestPointToSegment(Vector3 point, Vector3 segmentStart, Vector3 segmentEnd, out float t) - { - Vector3 relativePoint = point - segmentStart; - Vector3 segment = (segmentEnd - segmentStart); - Vector3 segmentDirection = segment.normalized; - float length = segment.magnitude; - - float dot = Vector3.Dot(relativePoint, segmentDirection); - - if (dot <= 0f) - dot = 0f; - else if (dot >= length) - dot = length; - - t = dot / length; - - return segmentStart + segment * t; - } - - private static float SqrDistanceToPolyLine(Vector3 point, Vector3[] points) - { - float minDistance = float.MaxValue; - - for (int i = 0; i < points.Length - 1; ++i) - { - float distance = SqrDistanceToSegment(point, points[i], points[i + 1]); - - if (distance < minDistance) - minDistance = distance; - } - - return minDistance; - } - - private static float SqrDistanceToSegment(Vector3 point, Vector3 segmentStart, Vector3 segmentEnd) - { - Vector3 relativePoint = point - segmentStart; - Vector3 segment = (segmentEnd - segmentStart); - Vector3 segmentDirection = segment.normalized; - float length = segment.magnitude; - - float dot = Vector3.Dot(relativePoint, segmentDirection); - - if (dot <= 0f) - return (point - segmentStart).sqrMagnitude; - else if (dot >= length) - return (point - segmentEnd).sqrMagnitude; - - return Vector3.Cross(relativePoint, segmentDirection).sqrMagnitude; - } - - private static bool Colinear(Vector3 v1, Vector3 v2, float error = 0.0001f) - { - return Mathf.Abs(v1.x * v2.y - v1.y * v2.x + v1.x * v2.z - v1.z * v2.x + v1.y * v2.z - v1.z * v2.y) < error; - } - } -} +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal static class BezierUtility + { + static Vector3[] s_TempPoints = new Vector3[3]; + + public static Vector3 BezierPoint(Vector3 startPosition, Vector3 startTangent, Vector3 endTangent, Vector3 endPosition, float t) + { + float s = 1.0f - t; + return startPosition * s * s * s + startTangent * s * s * t * 3.0f + endTangent * s * t * t * 3.0f + endPosition * t * t * t; + } + + public static Vector3 ClosestPointOnCurve(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, out float t) + { + Vector3 startToEnd = endPosition - startPosition; + Vector3 startToTangent = (startTangent - startPosition); + Vector3 endToTangent = (endTangent - endPosition); + + float sqrError = 0.001f; + + if (Colinear(startToTangent, startToEnd, sqrError) && Colinear(endToTangent, startToEnd, sqrError)) + return ClosestPointToSegment(point, startPosition, endPosition, out t); + + Vector3 leftStartPosition; + Vector3 leftEndPosition; + Vector3 leftStartTangent; + Vector3 leftEndTangent; + + Vector3 rightStartPosition; + Vector3 rightEndPosition; + Vector3 rightStartTangent; + Vector3 rightEndTangent; + + float leftStartT = 0f; + float leftEndT = 0.5f; + float rightStartT = 0.5f; + float rightEndT = 1f; + + SplitBezier(0.5f, startPosition, endPosition, startTangent, endTangent, + out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, + out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); + + Vector3 pointLeft = ClosestPointOnCurveIterative(point, leftStartPosition, leftEndPosition, leftStartTangent, leftEndTangent, sqrError, ref leftStartT, ref leftEndT); + Vector3 pointRight = ClosestPointOnCurveIterative(point, rightStartPosition, rightEndPosition, rightStartTangent, rightEndTangent, sqrError, ref rightStartT, ref rightEndT); + + if ((point - pointLeft).sqrMagnitude < (point - pointRight).sqrMagnitude) + { + t = leftStartT; + return pointLeft; + } + + t = rightStartT; + return pointRight; + } + + public static Vector3 ClosestPointOnCurveFast(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, out float t) + { + float sqrError = 0.001f; + float startT = 0f; + float endT = 1f; + + Vector3 closestPoint = ClosestPointOnCurveIterative(point, startPosition, endPosition, startTangent, endTangent, sqrError, ref startT, ref endT); + + t = startT; + + return closestPoint; + } + + private static Vector3 ClosestPointOnCurveIterative(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, float sqrError, ref float startT, ref float endT) + { + while ((startPosition - endPosition).sqrMagnitude > sqrError) + { + Vector3 startToEnd = endPosition - startPosition; + Vector3 startToTangent = (startTangent - startPosition); + Vector3 endToTangent = (endTangent - endPosition); + + if (Colinear(startToTangent, startToEnd, sqrError) && Colinear(endToTangent, startToEnd, sqrError)) + { + float t; + Vector3 closestPoint = ClosestPointToSegment(point, startPosition, endPosition, out t); + t *= (endT - startT); + startT += t; + endT -= t; + return closestPoint; + } + + Vector3 leftStartPosition; + Vector3 leftEndPosition; + Vector3 leftStartTangent; + Vector3 leftEndTangent; + + Vector3 rightStartPosition; + Vector3 rightEndPosition; + Vector3 rightStartTangent; + Vector3 rightEndTangent; + + SplitBezier(0.5f, startPosition, endPosition, startTangent, endTangent, + out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, + out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); + + s_TempPoints[0] = leftStartPosition; + s_TempPoints[1] = leftStartTangent; + s_TempPoints[2] = leftEndTangent; + + float sqrDistanceLeft = SqrDistanceToPolyLine(point, s_TempPoints); + + s_TempPoints[0] = rightEndPosition; + s_TempPoints[1] = rightEndTangent; + s_TempPoints[2] = rightStartTangent; + + float sqrDistanceRight = SqrDistanceToPolyLine(point, s_TempPoints); + + if (sqrDistanceLeft < sqrDistanceRight) + { + startPosition = leftStartPosition; + endPosition = leftEndPosition; + startTangent = leftStartTangent; + endTangent = leftEndTangent; + + endT -= (endT - startT) * 0.5f; + } + else + { + startPosition = rightStartPosition; + endPosition = rightEndPosition; + startTangent = rightStartTangent; + endTangent = rightEndTangent; + + startT += (endT - startT) * 0.5f; + } + } + + return endPosition; + } + + public static void SplitBezier(float t, Vector3 startPosition, Vector3 endPosition, Vector3 startRightTangent, Vector3 endLeftTangent, + out Vector3 leftStartPosition, out Vector3 leftEndPosition, out Vector3 leftStartTangent, out Vector3 leftEndTangent, + out Vector3 rightStartPosition, out Vector3 rightEndPosition, out Vector3 rightStartTangent, out Vector3 rightEndTangent) + { + Vector3 tangent0 = (startRightTangent - startPosition); + Vector3 tangent1 = (endLeftTangent - endPosition); + Vector3 tangentEdge = (endLeftTangent - startRightTangent); + + Vector3 tangentPoint0 = startPosition + tangent0 * t; + Vector3 tangentPoint1 = endPosition + tangent1 * (1f - t); + Vector3 tangentEdgePoint = startRightTangent + tangentEdge * t; + + Vector3 newTangent0 = tangentPoint0 + (tangentEdgePoint - tangentPoint0) * t; + Vector3 newTangent1 = tangentPoint1 + (tangentEdgePoint - tangentPoint1) * (1f - t); + Vector3 newTangentEdge = newTangent1 - newTangent0; + + Vector3 bezierPoint = newTangent0 + newTangentEdge * t; + + leftStartPosition = startPosition; + leftEndPosition = bezierPoint; + leftStartTangent = tangentPoint0; + leftEndTangent = newTangent0; + + rightStartPosition = bezierPoint; + rightEndPosition = endPosition; + rightStartTangent = newTangent1; + rightEndTangent = tangentPoint1; + } + + private static Vector3 ClosestPointToSegment(Vector3 point, Vector3 segmentStart, Vector3 segmentEnd, out float t) + { + Vector3 relativePoint = point - segmentStart; + Vector3 segment = (segmentEnd - segmentStart); + Vector3 segmentDirection = segment.normalized; + float length = segment.magnitude; + + float dot = Vector3.Dot(relativePoint, segmentDirection); + + if (dot <= 0f) + dot = 0f; + else if (dot >= length) + dot = length; + + t = dot / length; + + return segmentStart + segment * t; + } + + private static float SqrDistanceToPolyLine(Vector3 point, Vector3[] points) + { + float minDistance = float.MaxValue; + + for (int i = 0; i < points.Length - 1; ++i) + { + float distance = SqrDistanceToSegment(point, points[i], points[i + 1]); + + if (distance < minDistance) + minDistance = distance; + } + + return minDistance; + } + + private static float SqrDistanceToSegment(Vector3 point, Vector3 segmentStart, Vector3 segmentEnd) + { + Vector3 relativePoint = point - segmentStart; + Vector3 segment = (segmentEnd - segmentStart); + Vector3 segmentDirection = segment.normalized; + float length = segment.magnitude; + + float dot = Vector3.Dot(relativePoint, segmentDirection); + + if (dot <= 0f) + return (point - segmentStart).sqrMagnitude; + else if (dot >= length) + return (point - segmentEnd).sqrMagnitude; + + return Vector3.Cross(relativePoint, segmentDirection).sqrMagnitude; + } + + private static bool Colinear(Vector3 v1, Vector3 v2, float error = 0.0001f) + { + return Mathf.Abs(v1.x * v2.y - v1.y * v2.x + v1.x * v2.z - v1.z * v2.x + v1.y * v2.z - v1.z * v2.y) < error; + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs.meta b/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs.meta index 7646f5d..f852895 100644 --- a/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/BezierUtility.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 9c2696be9a3dd304782d2ecb29634bc3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 9c2696be9a3dd304782d2ecb29634bc3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs b/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs index e598332..01d1f79 100644 --- a/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs +++ b/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs @@ -1,73 +1,84 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal enum TangentMode - { - Linear = 0, - Continuous = 1, - Broken = 2 - } - - [Serializable] - internal struct TangentCache - { - public Vector3 leftTangent; - public Vector3 rightTangent; - } - - [Serializable] - internal struct ControlPoint - { - public Vector3 position; - public Vector3 localLeftTangent; - public Vector3 localRightTangent; - public TangentMode tangentMode; - public TangentCache continuousCache; - public TangentCache brokenCache; - public bool mirrorLeft; - - public Vector3 leftTangent - { - get { return localLeftTangent + position; } - set { localLeftTangent = value - position; } - } - - public Vector3 rightTangent - { - get { return localRightTangent + position; } - set { localRightTangent = value - position; } - } - - public void StoreTangents() - { - if (tangentMode == TangentMode.Continuous) - { - continuousCache.leftTangent = localLeftTangent; - continuousCache.rightTangent = localRightTangent; - } - else if (tangentMode == TangentMode.Broken) - { - brokenCache.leftTangent = localLeftTangent; - brokenCache.rightTangent = localRightTangent; - } - } - - public void RestoreTangents() - { - if (tangentMode == TangentMode.Continuous) - { - localLeftTangent = continuousCache.leftTangent; - localRightTangent = continuousCache.rightTangent; - } - else if (tangentMode == TangentMode.Broken) - { - localLeftTangent = brokenCache.leftTangent; - localRightTangent = brokenCache.rightTangent; - } - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal enum TangentMode + { + Linear = 0, + Continuous = 1, + Broken = 2 + } + + [Serializable] + internal struct TangentCache + { + public Vector3 leftTangent; + public Vector3 rightTangent; + } + + [Serializable] + internal struct ControlPoint + { + public Vector3 position; + public Vector3 localLeftTangent; + public Vector3 localRightTangent; + public TangentMode tangentMode; + public TangentCache continuousCache; + public TangentCache brokenCache; + public bool mirrorLeft; + + public ControlPoint(Vector3 pos) + { + position = pos; + localLeftTangent = Vector3.zero; + localRightTangent = Vector3.zero; + tangentMode = TangentMode.Linear; + continuousCache = default(TangentCache); + brokenCache = default(TangentCache); + mirrorLeft = false; + } + + public Vector3 leftTangent + { + get { return localLeftTangent + position; } + set { localLeftTangent = value - position; } + } + + public Vector3 rightTangent + { + get { return localRightTangent + position; } + set { localRightTangent = value - position; } + } + + public void StoreTangents() + { + if (tangentMode == TangentMode.Continuous) + { + continuousCache.leftTangent = localLeftTangent; + continuousCache.rightTangent = localRightTangent; + } + else if (tangentMode == TangentMode.Broken) + { + brokenCache.leftTangent = localLeftTangent; + brokenCache.rightTangent = localRightTangent; + } + } + + public void RestoreTangents() + { + if (tangentMode == TangentMode.Continuous) + { + localLeftTangent = continuousCache.leftTangent; + localRightTangent = continuousCache.rightTangent; + } + else if (tangentMode == TangentMode.Broken) + { + localLeftTangent = brokenCache.leftTangent; + localRightTangent = brokenCache.rightTangent; + } + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs.meta b/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs.meta index dcb759e..3e3af0a 100644 --- a/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/ControlPoint.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: efb78f838bdce7241ac8782083ef55b1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: efb78f838bdce7241ac8782083ef55b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs b/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs index 27471d3..c6d6638 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs @@ -1,147 +1,151 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - [Serializable] - internal class EditablePath : IEditablePath - { - [SerializeField] - private ShapeType m_ShapeType; - [SerializeField] - private IndexedSelection m_Selection = new IndexedSelection(); - [SerializeField] - private List m_ControlPoints = new List(); - [SerializeField] - private bool m_IsOpenEnded; - private Matrix4x4 m_LocalToWorldMatrix = Matrix4x4.identity; - private Matrix4x4 m_WorldToLocalMatrix = Matrix4x4.identity; - private Vector3 m_Forward = Vector3.forward; - private Vector3 m_Up = Vector3.up; - private Vector3 m_Right = Vector3.right; - - public ShapeType shapeType - { - get { return m_ShapeType; } - set { m_ShapeType = value; } - } - - public IUndoObject undoObject { get; set; } - - public Matrix4x4 localToWorldMatrix - { - get { return m_LocalToWorldMatrix; } - set - { - m_LocalToWorldMatrix = value; - m_WorldToLocalMatrix = value.inverse; - } - } - - public Vector3 forward - { - get { return m_Forward; } - set { m_Forward = value; } - } - - public Vector3 up - { - get { return m_Up; } - set { m_Up = value; } - } - - public Vector3 right - { - get { return m_Right; } - set { m_Right = value; } - } - - public Matrix4x4 worldToLocalMatrix - { - get { return m_WorldToLocalMatrix; } - } - - public bool isOpenEnded - { - get - { - if (pointCount < 3) - return true; - - return m_IsOpenEnded; - } - set { m_IsOpenEnded = value; } - } - - public ISelection selection - { - get { return m_Selection; } - } - - public int pointCount - { - get { return m_ControlPoints.Count; } - } - - public ControlPoint GetPoint(int index) - { - return TransformPoint(localToWorldMatrix, m_ControlPoints[index]); - } - - public void SetPoint(int index, ControlPoint controlPoint) - { - m_ControlPoints[index] = TransformPoint(worldToLocalMatrix, controlPoint); - } - - public void AddPoint(ControlPoint controlPoint) - { - m_ControlPoints.Insert(pointCount, TransformPoint(worldToLocalMatrix, controlPoint)); - } - - public void InsertPoint(int index, ControlPoint controlPoint) - { - m_ControlPoints.Insert(index, TransformPoint(worldToLocalMatrix, controlPoint)); - } - - public void RemovePoint(int index) - { - m_ControlPoints.RemoveAt(index); - } - - public void Clear() - { - m_ControlPoints.Clear(); - } - - private ControlPoint TransformPoint(Matrix4x4 transformMatrix, ControlPoint controlPoint) - { - if (transformMatrix == Matrix4x4.identity) - return controlPoint; - - var newControlPoint = new ControlPoint() - { - position = transformMatrix.MultiplyPoint3x4(controlPoint.position), - tangentMode = controlPoint.tangentMode, - continuousCache = controlPoint.continuousCache, - brokenCache = controlPoint.brokenCache, - mirrorLeft = controlPoint.mirrorLeft - }; - - newControlPoint.rightTangent = transformMatrix.MultiplyPoint3x4(controlPoint.rightTangent); - newControlPoint.leftTangent = transformMatrix.MultiplyPoint3x4(controlPoint.leftTangent); - - return newControlPoint; - } - - public bool Select(ISelector selector) - { - var changed = false; - - for (var i = 0; i < pointCount; ++i) - changed |= selection.Select(i, selector.Select(GetPoint(i).position)); - - return changed; - } - } -} +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + [Serializable] + internal class EditablePath : IEditablePath + { + [SerializeField] + private ShapeType m_ShapeType; + [SerializeField] + private IndexedSelection m_Selection = new IndexedSelection(); + [SerializeField] + private List m_ControlPoints = new List(); + [SerializeField] + private bool m_IsOpenEnded; + private Matrix4x4 m_LocalToWorldMatrix = Matrix4x4.identity; + private Matrix4x4 m_WorldToLocalMatrix = Matrix4x4.identity; + private Vector3 m_Forward = Vector3.forward; + private Vector3 m_Up = Vector3.up; + private Vector3 m_Right = Vector3.right; + + public ShapeType shapeType + { + get { return m_ShapeType; } + set { m_ShapeType = value; } + } + + public IUndoObject undoObject { get; set; } + + public Matrix4x4 localToWorldMatrix + { + get { return m_LocalToWorldMatrix; } + set + { + m_LocalToWorldMatrix = value; + m_WorldToLocalMatrix = value.inverse; + } + } + + public Vector3 forward + { + get { return m_Forward; } + set { m_Forward = value; } + } + + public Vector3 up + { + get { return m_Up; } + set { m_Up = value; } + } + + public Vector3 right + { + get { return m_Right; } + set { m_Right = value; } + } + + public Matrix4x4 worldToLocalMatrix + { + get { return m_WorldToLocalMatrix; } + } + + public bool isOpenEnded + { + get + { + if (pointCount < 3) + return true; + + return m_IsOpenEnded; + } + set { m_IsOpenEnded = value; } + } + + public ISelection selection + { + get { return m_Selection; } + } + + public int pointCount + { + get { return m_ControlPoints.Count; } + } + + public ControlPoint GetPoint(int index) + { + return TransformPoint(localToWorldMatrix, m_ControlPoints[index]); + } + + public void SetPoint(int index, ControlPoint controlPoint) + { + m_ControlPoints[index] = TransformPoint(worldToLocalMatrix, controlPoint); + } + + public void AddPoint(ControlPoint controlPoint) + { + m_ControlPoints.Insert(pointCount, TransformPoint(worldToLocalMatrix, controlPoint)); + } + + public void InsertPoint(int index, ControlPoint controlPoint) + { + m_ControlPoints.Insert(index, TransformPoint(worldToLocalMatrix, controlPoint)); + } + + public void RemovePoint(int index) + { + m_ControlPoints.RemoveAt(index); + } + + public void Clear() + { + m_ControlPoints.Clear(); + } + + private ControlPoint TransformPoint(Matrix4x4 transformMatrix, ControlPoint controlPoint) + { + if (transformMatrix == Matrix4x4.identity) + return controlPoint; + + var newControlPoint = new ControlPoint() + { + position = transformMatrix.MultiplyPoint3x4(controlPoint.position), + tangentMode = controlPoint.tangentMode, + continuousCache = controlPoint.continuousCache, + brokenCache = controlPoint.brokenCache, + mirrorLeft = controlPoint.mirrorLeft + }; + + newControlPoint.rightTangent = transformMatrix.MultiplyPoint3x4(controlPoint.rightTangent); + newControlPoint.leftTangent = transformMatrix.MultiplyPoint3x4(controlPoint.leftTangent); + + return newControlPoint; + } + + public bool Select(ISelector selector) + { + var changed = false; + + for (var i = 0; i < pointCount; ++i) + changed |= selection.Select(i, selector.Select(GetPoint(i).position)); + + return changed; + } + + public virtual void SetDefaultShape() + { + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs.meta b/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs.meta index 99cd0df..89cf878 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePath.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 1dc00ea1dcadc3e4eb2fb4d09e84101c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 1dc00ea1dcadc3e4eb2fb4d09e84101c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs b/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs index 1b50b1e..2570b99 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs @@ -1,255 +1,264 @@ -using System; -using System.Linq; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class EditablePathController : IEditablePathController - { - private ISnapping m_Snapping = new Snapping(); - - public IEditablePath editablePath { get; set; } - public IEditablePath closestEditablePath { get { return editablePath; } } - - public ISnapping snapping - { - get { return m_Snapping; } - set { m_Snapping = value; } - } - - public bool enableSnapping { get; set; } - - public void RegisterUndo(string name) - { - if (editablePath.undoObject != null) - editablePath.undoObject.RegisterUndo(name); - } - - public void ClearSelection() - { - editablePath.selection.Clear(); - } - - public void SelectPoint(int index, bool select) - { - editablePath.selection.Select(index, select); - } - - public void CreatePoint(int index, Vector3 position) - { - ClearSelection(); - - if (editablePath.shapeType == ShapeType.Polygon) - { - editablePath.InsertPoint(index + 1, new ControlPoint() { position = position }); - } - else if (editablePath.shapeType == ShapeType.Spline) - { - var nextIndex = NextIndex(index); - var currentPoint = editablePath.GetPoint(index); - var nextPoint = editablePath.GetPoint(nextIndex); - - float t; - var closestPoint = BezierUtility.ClosestPointOnCurve( - position, - currentPoint.position, - nextPoint.position, - GetRightTangentPosition(index), - GetLeftTangentPosition(nextIndex), - out t); - - Vector3 leftStartPosition; - Vector3 leftEndPosition; - Vector3 leftStartTangent; - Vector3 leftEndTangent; - - Vector3 rightStartPosition; - Vector3 rightEndPosition; - Vector3 rightStartTangent; - Vector3 rightEndTangent; - - BezierUtility.SplitBezier(t, currentPoint.position, nextPoint.position, GetRightTangentPosition(index), GetLeftTangentPosition(nextIndex), - out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, - out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); - - var newPointIndex = index + 1; - var newPoint = new ControlPoint() - { - position = closestPoint, - leftTangent = leftEndTangent, - rightTangent = rightStartTangent, - tangentMode = TangentMode.Continuous - }; - - currentPoint.rightTangent = leftStartTangent; - nextPoint.leftTangent = rightEndTangent; - - if (currentPoint.tangentMode == TangentMode.Linear && nextPoint.tangentMode == TangentMode.Linear) - { - newPoint.tangentMode = TangentMode.Linear; - newPoint.localLeftTangent = Vector3.zero; - newPoint.localRightTangent = Vector3.zero; - currentPoint.localRightTangent = Vector3.zero; - nextPoint.localLeftTangent = Vector3.zero; - } - else - { - if (currentPoint.tangentMode == TangentMode.Linear) - currentPoint.tangentMode = TangentMode.Broken; - - if (nextPoint.tangentMode == TangentMode.Linear) - nextPoint.tangentMode = TangentMode.Broken; - } - - editablePath.SetPoint(index, currentPoint); - editablePath.SetPoint(nextIndex, nextPoint); - editablePath.InsertPoint(newPointIndex, newPoint); - } - } - - public void RemoveSelectedPoints() - { - var minPointCount = editablePath.isOpenEnded ? 2 : 3; - - if (editablePath.pointCount > minPointCount) - { - var indices = editablePath.selection.elements.OrderByDescending( i => i); - - foreach (var index in indices) - if (editablePath.pointCount > minPointCount) - editablePath.RemovePoint(index); - - ClearSelection(); - } - } - - public void MoveSelectedPoints(Vector3 delta) - { - delta = Vector3.ProjectOnPlane(delta, editablePath.forward); - - for (var i = 0; i < editablePath.pointCount; ++i) - { - if (editablePath.selection.Contains(i)) - { - var controlPoint = editablePath.GetPoint(i); - controlPoint.position += delta; - editablePath.SetPoint(i, controlPoint); - } - } - } - - public void MoveEdge(int index, Vector3 delta) - { - if (editablePath.isOpenEnded && index == editablePath.pointCount - 1) - return; - - var controlPoint = editablePath.GetPoint(index); - controlPoint.position += delta; - editablePath.SetPoint(index, controlPoint); - controlPoint = NextControlPoint(index); - controlPoint.position += delta; - editablePath.SetPoint(NextIndex(index), controlPoint); - } - - public void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent) - { - var controlPoint = editablePath.GetPoint(index); - controlPoint.leftTangent = position; - controlPoint.mirrorLeft = false; - - if (setToLinear) - { - controlPoint.leftTangent = controlPoint.position; - controlPoint.rightTangent = cachedRightTangent; - } - else if (controlPoint.tangentMode == TangentMode.Continuous || mirror) - { - var magnitude = controlPoint.localRightTangent.magnitude; - - if (mirror) - magnitude = controlPoint.localLeftTangent.magnitude; - - controlPoint.localRightTangent = magnitude * -controlPoint.localLeftTangent.normalized; - } - - editablePath.SetPoint(index, controlPoint); - } - - public void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent) - { - var controlPoint = editablePath.GetPoint(index); - controlPoint.rightTangent = position; - controlPoint.mirrorLeft = true; - - if (setToLinear) - { - controlPoint.rightTangent = controlPoint.position; - controlPoint.leftTangent = cachedLeftTangent; - } - else if (controlPoint.tangentMode == TangentMode.Continuous || mirror) - { - var magnitude = controlPoint.localLeftTangent.magnitude; - - if (mirror) - magnitude = controlPoint.localRightTangent.magnitude; - - controlPoint.localLeftTangent = magnitude * -controlPoint.localRightTangent.normalized; - } - - editablePath.SetPoint(index, controlPoint); - } - - public void ClearClosestPath() { } - public void AddClosestPath(float distance) { } - - private Vector3 GetLeftTangentPosition(int index) - { - var isLinear = Mathf.Approximately(editablePath.GetPoint(index).localLeftTangent.sqrMagnitude, 0f); - - if (isLinear) - { - var position = editablePath.GetPoint(index).position; - var prevPosition = PrevControlPoint(index).position; - - return (1f / 3f) * (prevPosition - position) + position; - } - - return editablePath.GetPoint(index).leftTangent; - } - - private Vector3 GetRightTangentPosition(int index) - { - var isLinear = Mathf.Approximately(editablePath.GetPoint(index).localRightTangent.sqrMagnitude, 0f); - - if (isLinear) - { - var position = editablePath.GetPoint(index).position; - var nextPosition = NextControlPoint(index).position; - - return (1f / 3f) * (nextPosition - position) + position; - } - - return editablePath.GetPoint(index).rightTangent; - } - - private int NextIndex(int index) - { - return EditablePathUtility.Mod(index + 1, editablePath.pointCount); - } - - private ControlPoint NextControlPoint(int index) - { - return editablePath.GetPoint(NextIndex(index)); - } - - private int PrevIndex(int index) - { - return EditablePathUtility.Mod(index - 1, editablePath.pointCount); - } - - private ControlPoint PrevControlPoint(int index) - { - return editablePath.GetPoint(PrevIndex(index)); - } - } -} +using System; +using System.Linq; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class EditablePathController : IEditablePathController + { + private ISnapping m_Snapping = new Snapping(); + + public IEditablePath editablePath { get; set; } + public IEditablePath closestEditablePath { get { return editablePath; } } + + public ISnapping snapping + { + get { return m_Snapping; } + set { m_Snapping = value; } + } + + public bool enableSnapping { get; set; } + + public void RegisterUndo(string name) + { + if (editablePath.undoObject != null) + editablePath.undoObject.RegisterUndo(name); + } + + public void ClearSelection() + { + editablePath.selection.Clear(); + } + + public void SelectPoint(int index, bool select) + { + editablePath.selection.Select(index, select); + } + + public void CreatePoint(int index, Vector3 position) + { + ClearSelection(); + + if (editablePath.shapeType == ShapeType.Polygon) + { + editablePath.InsertPoint(index + 1, new ControlPoint() { position = position }); + } + else if (editablePath.shapeType == ShapeType.Spline) + { + var nextIndex = NextIndex(index); + var currentPoint = editablePath.GetPoint(index); + var nextPoint = editablePath.GetPoint(nextIndex); + + float t; + var closestPoint = BezierUtility.ClosestPointOnCurve( + position, + currentPoint.position, + nextPoint.position, + GetRightTangentPosition(index), + GetLeftTangentPosition(nextIndex), + out t); + + Vector3 leftStartPosition; + Vector3 leftEndPosition; + Vector3 leftStartTangent; + Vector3 leftEndTangent; + + Vector3 rightStartPosition; + Vector3 rightEndPosition; + Vector3 rightStartTangent; + Vector3 rightEndTangent; + + BezierUtility.SplitBezier(t, currentPoint.position, nextPoint.position, GetRightTangentPosition(index), GetLeftTangentPosition(nextIndex), + out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, + out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); + + var newPointIndex = index + 1; + var newPoint = new ControlPoint() + { + position = closestPoint, + leftTangent = leftEndTangent, + rightTangent = rightStartTangent, + tangentMode = TangentMode.Continuous + }; + + currentPoint.rightTangent = leftStartTangent; + nextPoint.leftTangent = rightEndTangent; + + if (currentPoint.tangentMode == TangentMode.Linear && nextPoint.tangentMode == TangentMode.Linear) + { + newPoint.tangentMode = TangentMode.Linear; + newPoint.localLeftTangent = Vector3.zero; + newPoint.localRightTangent = Vector3.zero; + currentPoint.localRightTangent = Vector3.zero; + nextPoint.localLeftTangent = Vector3.zero; + } + else + { + if (currentPoint.tangentMode == TangentMode.Linear) + currentPoint.tangentMode = TangentMode.Broken; + + if (nextPoint.tangentMode == TangentMode.Linear) + nextPoint.tangentMode = TangentMode.Broken; + } + + editablePath.SetPoint(index, currentPoint); + editablePath.SetPoint(nextIndex, nextPoint); + editablePath.InsertPoint(newPointIndex, newPoint); + } + } + + public void RemoveSelectedPoints() + { + var minPointCount = editablePath.isOpenEnded ? 2 : 3; + int pointsCountToRemove = editablePath.selection.Count; + + if (editablePath.pointCount != pointsCountToRemove) + { + var indices = editablePath.selection.elements.OrderByDescending(i => i); + + foreach (var index in indices) + { + if (editablePath.pointCount > minPointCount) + { + editablePath.RemovePoint(index); + } + } + ClearSelection(); + } + else + { + editablePath.SetDefaultShape(); + ClearSelection(); + } + } + + public void MoveSelectedPoints(Vector3 delta) + { + delta = Vector3.ProjectOnPlane(delta, editablePath.forward); + + for (var i = 0; i < editablePath.pointCount; ++i) + { + if (editablePath.selection.Contains(i)) + { + var controlPoint = editablePath.GetPoint(i); + controlPoint.position += delta; + editablePath.SetPoint(i, controlPoint); + } + } + } + + public void MoveEdge(int index, Vector3 delta) + { + if (editablePath.isOpenEnded && index == editablePath.pointCount - 1) + return; + + var controlPoint = editablePath.GetPoint(index); + controlPoint.position += delta; + editablePath.SetPoint(index, controlPoint); + controlPoint = NextControlPoint(index); + controlPoint.position += delta; + editablePath.SetPoint(NextIndex(index), controlPoint); + } + + public void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent) + { + var controlPoint = editablePath.GetPoint(index); + controlPoint.leftTangent = position; + controlPoint.mirrorLeft = false; + + if (setToLinear) + { + controlPoint.leftTangent = controlPoint.position; + controlPoint.rightTangent = cachedRightTangent; + } + else if (controlPoint.tangentMode == TangentMode.Continuous || mirror) + { + var magnitude = controlPoint.localRightTangent.magnitude; + + if (mirror) + magnitude = controlPoint.localLeftTangent.magnitude; + + controlPoint.localRightTangent = magnitude * -controlPoint.localLeftTangent.normalized; + } + + editablePath.SetPoint(index, controlPoint); + } + + public void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent) + { + var controlPoint = editablePath.GetPoint(index); + controlPoint.rightTangent = position; + controlPoint.mirrorLeft = true; + + if (setToLinear) + { + controlPoint.rightTangent = controlPoint.position; + controlPoint.leftTangent = cachedLeftTangent; + } + else if (controlPoint.tangentMode == TangentMode.Continuous || mirror) + { + var magnitude = controlPoint.localLeftTangent.magnitude; + + if (mirror) + magnitude = controlPoint.localRightTangent.magnitude; + + controlPoint.localLeftTangent = magnitude * -controlPoint.localRightTangent.normalized; + } + + editablePath.SetPoint(index, controlPoint); + } + + public void ClearClosestPath() { } + public void AddClosestPath(float distance) { } + + private Vector3 GetLeftTangentPosition(int index) + { + var isLinear = Mathf.Approximately(editablePath.GetPoint(index).localLeftTangent.sqrMagnitude, 0f); + + if (isLinear) + { + var position = editablePath.GetPoint(index).position; + var prevPosition = PrevControlPoint(index).position; + + return (1f / 3f) * (prevPosition - position) + position; + } + + return editablePath.GetPoint(index).leftTangent; + } + + private Vector3 GetRightTangentPosition(int index) + { + var isLinear = Mathf.Approximately(editablePath.GetPoint(index).localRightTangent.sqrMagnitude, 0f); + + if (isLinear) + { + var position = editablePath.GetPoint(index).position; + var nextPosition = NextControlPoint(index).position; + + return (1f / 3f) * (nextPosition - position) + position; + } + + return editablePath.GetPoint(index).rightTangent; + } + + private int NextIndex(int index) + { + return EditablePathUtility.Mod(index + 1, editablePath.pointCount); + } + + private ControlPoint NextControlPoint(int index) + { + return editablePath.GetPoint(NextIndex(index)); + } + + private int PrevIndex(int index) + { + return EditablePathUtility.Mod(index - 1, editablePath.pointCount); + } + + private ControlPoint PrevControlPoint(int index) + { + return editablePath.GetPoint(PrevIndex(index)); + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs.meta b/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs.meta index fe4a37d..448aa24 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePathController.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 84aa007ed10d73d43a9e41411b55a886 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 84aa007ed10d73d43a9e41411b55a886 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs b/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs index 6d9b222..c072925 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs @@ -1,275 +1,275 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal static class EditablePathExtensions - { - public static Polygon ToPolygon(this IEditablePath path) - { - var polygon = new Polygon() - { - isOpenEnded = path.isOpenEnded, - points = new Vector3[path.pointCount] - }; - - for (var i = 0; i < path.pointCount; ++i) - polygon.points[i] = path.GetPoint(i).position; - - return polygon; - } - - public static Spline ToSpline(this IEditablePath path) - { - var count = path.pointCount * 3; - - if (path.isOpenEnded) - count -= 2; - - var spline = new Spline() - { - isOpenEnded = path.isOpenEnded, - points = new Vector3[count] - }; - - for (var i = 0; i < path.pointCount; ++i) - { - var point = path.GetPoint(i); - - spline.points[i*3] = point.position; - - if (i * 3 + 1 < count) - { - var nextIndex = EditablePathUtility.Mod(i+1, path.pointCount); - - spline.points[i*3 + 1] = path.CalculateRightTangent(i); - spline.points[i*3 + 2] = path.CalculateLeftTangent(nextIndex); - } - } - - return spline; - } - - public static Vector3 CalculateLocalLeftTangent(this IEditablePath path, int index) - { - return path.CalculateLeftTangent(index) - path.GetPoint(index).position; - } - - public static Vector3 CalculateLeftTangent(this IEditablePath path, int index) - { - var point = path.GetPoint(index); - var isTangentLinear = point.localLeftTangent == Vector3.zero; - var isEndpoint = path.isOpenEnded && index == 0; - var tangent = point.leftTangent; - - if (isEndpoint) - return point.position; - - if (isTangentLinear) - { - var prevPoint = path.GetPrevPoint(index); - var v = prevPoint.position - point.position; - tangent = point.position + v.normalized * (v.magnitude / 3f); - } - - return tangent; - } - - public static Vector3 CalculateLocalRightTangent(this IEditablePath path, int index) - { - return path.CalculateRightTangent(index) - path.GetPoint(index).position; - } - - public static Vector3 CalculateRightTangent(this IEditablePath path, int index) - { - var point = path.GetPoint(index); - var isTangentLinear = point.localRightTangent == Vector3.zero; - var isEndpoint = path.isOpenEnded && index == path.pointCount - 1; - var tangent = point.rightTangent; - - if (isEndpoint) - return point.position; - - if (isTangentLinear) - { - var nextPoint = path.GetNextPoint(index); - var v = nextPoint.position - point.position; - tangent = point.position + v.normalized * (v.magnitude / 3f); - } - - return tangent; - } - - public static ControlPoint GetPrevPoint(this IEditablePath path, int index) - { - return path.GetPoint(EditablePathUtility.Mod(index - 1, path.pointCount)); - } - - public static ControlPoint GetNextPoint(this IEditablePath path, int index) - { - return path.GetPoint(EditablePathUtility.Mod(index + 1, path.pointCount)); - } - - public static void UpdateTangentMode(this IEditablePath path, int index) - { - var localToWorldMatrix = path.localToWorldMatrix; - path.localToWorldMatrix = Matrix4x4.identity; - - var controlPoint = path.GetPoint(index); - var isLeftTangentLinear = controlPoint.localLeftTangent == Vector3.zero; - var isRightTangentLinear = controlPoint.localRightTangent == Vector3.zero; - - if (isLeftTangentLinear && isRightTangentLinear) - controlPoint.tangentMode = TangentMode.Linear; - else if (isLeftTangentLinear || isRightTangentLinear) - controlPoint.tangentMode = TangentMode.Broken; - else if (controlPoint.tangentMode != TangentMode.Continuous) - controlPoint.tangentMode = TangentMode.Broken; - - controlPoint.StoreTangents(); - path.SetPoint(index, controlPoint); - path.localToWorldMatrix = localToWorldMatrix; - } - - public static void UpdateTangentsFromMode(this IEditablePath path) - { - const float kEpsilon = 0.001f; - - var localToWorldMatrix = path.localToWorldMatrix; - path.localToWorldMatrix = Matrix4x4.identity; - - for (var i = 0; i < path.pointCount; ++i) - { - var controlPoint = path.GetPoint(i); - - if (controlPoint.tangentMode == TangentMode.Linear) - { - controlPoint.localLeftTangent = Vector3.zero; - controlPoint.localRightTangent = Vector3.zero; - } - else if (controlPoint.tangentMode == TangentMode.Broken) - { - var isLeftEndpoint = path.isOpenEnded && i == 0; - var prevPoint = path.GetPrevPoint(i); - var nextPoint = path.GetNextPoint(i); - - var liniarLeftPosition = (prevPoint.position - controlPoint.position) / 3f; - var isLeftTangentLinear = isLeftEndpoint || (controlPoint.localLeftTangent - liniarLeftPosition).sqrMagnitude < kEpsilon; - - if (isLeftTangentLinear) - controlPoint.localLeftTangent = Vector3.zero; - - var isRightEndpoint = path.isOpenEnded && i == path.pointCount-1; - var liniarRightPosition = (nextPoint.position - controlPoint.position) / 3f; - var isRightTangentLinear = isRightEndpoint || (controlPoint.localRightTangent - liniarRightPosition).sqrMagnitude < kEpsilon; - - if (isRightTangentLinear) - controlPoint.localRightTangent = Vector3.zero; - - if (isLeftTangentLinear && isRightTangentLinear) - controlPoint.tangentMode = TangentMode.Linear; - } - else if (controlPoint.tangentMode == TangentMode.Continuous) - { - //TODO: ensure tangent continuity - } - - controlPoint.StoreTangents(); - path.SetPoint(i, controlPoint); - } - - path.localToWorldMatrix = localToWorldMatrix; - } - - public static void SetTangentMode(this IEditablePath path, int index, TangentMode tangentMode) - { - var localToWorldMatrix = path.localToWorldMatrix; - path.localToWorldMatrix = Matrix4x4.identity; - - var controlPoint = path.GetPoint(index); - var isEndpoint = path.isOpenEnded && (index == 0 || index == path.pointCount - 1); - var oldTangentMode = controlPoint.tangentMode; - - controlPoint.tangentMode = tangentMode; - controlPoint.RestoreTangents(); - - if (tangentMode == TangentMode.Linear) - { - controlPoint.localLeftTangent = Vector3.zero; - controlPoint.localRightTangent = Vector3.zero; - } - else if (tangentMode == TangentMode.Continuous && !isEndpoint) - { - var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero; - var isRightLinear = controlPoint.localRightTangent == Vector3.zero; - var tangentDotProduct = Vector3.Dot(controlPoint.localLeftTangent.normalized, controlPoint.localRightTangent.normalized); - var isContinous = tangentDotProduct < 0f && (tangentDotProduct + 1) < 0.001f; - var isLinear = isLeftLinear && isRightLinear; - - if ((isLinear || oldTangentMode == TangentMode.Broken) && !isContinous) - { - var prevPoint = path.GetPrevPoint(index); - var nextPoint = path.GetNextPoint(index); - var vLeft = prevPoint.position - controlPoint.position; - var vRight = nextPoint.position - controlPoint.position; - var rightDirection = Vector3.Cross(Vector3.Cross(vLeft, vRight), vLeft.normalized + vRight.normalized).normalized; - var scale = 1f / 3f; - - if (isLeftLinear) - controlPoint.localLeftTangent = vLeft.magnitude * scale * -rightDirection; - else - controlPoint.localLeftTangent = controlPoint.localLeftTangent.magnitude * -rightDirection; - - if (isRightLinear) - controlPoint.localRightTangent = vRight.magnitude * scale * rightDirection; - else - controlPoint.localRightTangent = controlPoint.localRightTangent.magnitude * rightDirection; - } - } - else - { - var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero; - var isRightLinear = controlPoint.localRightTangent == Vector3.zero; - - if (isLeftLinear || isRightLinear) - { - if (isLeftLinear) - controlPoint.localLeftTangent = path.CalculateLocalLeftTangent(index); - - if (isRightLinear) - controlPoint.localRightTangent = path.CalculateLocalRightTangent(index); - } - } - - controlPoint.StoreTangents(); - path.SetPoint(index, controlPoint); - path.localToWorldMatrix = localToWorldMatrix; - } - - public static void MirrorTangent(this IEditablePath path, int index) - { - var localToWorldMatrix = path.localToWorldMatrix; - path.localToWorldMatrix = Matrix4x4.identity; - - var controlPoint = path.GetPoint(index); - - if (controlPoint.tangentMode == TangentMode.Linear) - return; - - if (!Mathf.Approximately((controlPoint.localLeftTangent + controlPoint.localRightTangent).sqrMagnitude, 0f)) - { - if (controlPoint.mirrorLeft) - controlPoint.localLeftTangent = -controlPoint.localRightTangent; - else - controlPoint.localRightTangent = -controlPoint.localLeftTangent; - - controlPoint.StoreTangents(); - path.SetPoint(index, controlPoint); - } - - path.localToWorldMatrix = localToWorldMatrix; - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal static class EditablePathExtensions + { + public static Polygon ToPolygon(this IEditablePath path) + { + var polygon = new Polygon() + { + isOpenEnded = path.isOpenEnded, + points = new Vector3[path.pointCount] + }; + + for (var i = 0; i < path.pointCount; ++i) + polygon.points[i] = path.GetPoint(i).position; + + return polygon; + } + + public static Spline ToSpline(this IEditablePath path) + { + var count = path.pointCount * 3; + + if (path.isOpenEnded) + count -= 2; + + var spline = new Spline() + { + isOpenEnded = path.isOpenEnded, + points = new Vector3[count] + }; + + for (var i = 0; i < path.pointCount; ++i) + { + var point = path.GetPoint(i); + + spline.points[i * 3] = point.position; + + if (i * 3 + 1 < count) + { + var nextIndex = EditablePathUtility.Mod(i + 1, path.pointCount); + + spline.points[i * 3 + 1] = path.CalculateRightTangent(i); + spline.points[i * 3 + 2] = path.CalculateLeftTangent(nextIndex); + } + } + + return spline; + } + + public static Vector3 CalculateLocalLeftTangent(this IEditablePath path, int index) + { + return path.CalculateLeftTangent(index) - path.GetPoint(index).position; + } + + public static Vector3 CalculateLeftTangent(this IEditablePath path, int index) + { + var point = path.GetPoint(index); + var isTangentLinear = point.localLeftTangent == Vector3.zero; + var isEndpoint = path.isOpenEnded && index == 0; + var tangent = point.leftTangent; + + if (isEndpoint) + return point.position; + + if (isTangentLinear) + { + var prevPoint = path.GetPrevPoint(index); + var v = prevPoint.position - point.position; + tangent = point.position + v.normalized * (v.magnitude / 3f); + } + + return tangent; + } + + public static Vector3 CalculateLocalRightTangent(this IEditablePath path, int index) + { + return path.CalculateRightTangent(index) - path.GetPoint(index).position; + } + + public static Vector3 CalculateRightTangent(this IEditablePath path, int index) + { + var point = path.GetPoint(index); + var isTangentLinear = point.localRightTangent == Vector3.zero; + var isEndpoint = path.isOpenEnded && index == path.pointCount - 1; + var tangent = point.rightTangent; + + if (isEndpoint) + return point.position; + + if (isTangentLinear) + { + var nextPoint = path.GetNextPoint(index); + var v = nextPoint.position - point.position; + tangent = point.position + v.normalized * (v.magnitude / 3f); + } + + return tangent; + } + + public static ControlPoint GetPrevPoint(this IEditablePath path, int index) + { + return path.GetPoint(EditablePathUtility.Mod(index - 1, path.pointCount)); + } + + public static ControlPoint GetNextPoint(this IEditablePath path, int index) + { + return path.GetPoint(EditablePathUtility.Mod(index + 1, path.pointCount)); + } + + public static void UpdateTangentMode(this IEditablePath path, int index) + { + var localToWorldMatrix = path.localToWorldMatrix; + path.localToWorldMatrix = Matrix4x4.identity; + + var controlPoint = path.GetPoint(index); + var isLeftTangentLinear = controlPoint.localLeftTangent == Vector3.zero; + var isRightTangentLinear = controlPoint.localRightTangent == Vector3.zero; + + if (isLeftTangentLinear && isRightTangentLinear) + controlPoint.tangentMode = TangentMode.Linear; + else if (isLeftTangentLinear || isRightTangentLinear) + controlPoint.tangentMode = TangentMode.Broken; + else if (controlPoint.tangentMode != TangentMode.Continuous) + controlPoint.tangentMode = TangentMode.Broken; + + controlPoint.StoreTangents(); + path.SetPoint(index, controlPoint); + path.localToWorldMatrix = localToWorldMatrix; + } + + public static void UpdateTangentsFromMode(this IEditablePath path) + { + const float kEpsilon = 0.001f; + + var localToWorldMatrix = path.localToWorldMatrix; + path.localToWorldMatrix = Matrix4x4.identity; + + for (var i = 0; i < path.pointCount; ++i) + { + var controlPoint = path.GetPoint(i); + + if (controlPoint.tangentMode == TangentMode.Linear) + { + controlPoint.localLeftTangent = Vector3.zero; + controlPoint.localRightTangent = Vector3.zero; + } + else if (controlPoint.tangentMode == TangentMode.Broken) + { + var isLeftEndpoint = path.isOpenEnded && i == 0; + var prevPoint = path.GetPrevPoint(i); + var nextPoint = path.GetNextPoint(i); + + var liniarLeftPosition = (prevPoint.position - controlPoint.position) / 3f; + var isLeftTangentLinear = isLeftEndpoint || (controlPoint.localLeftTangent - liniarLeftPosition).sqrMagnitude < kEpsilon; + + if (isLeftTangentLinear) + controlPoint.localLeftTangent = Vector3.zero; + + var isRightEndpoint = path.isOpenEnded && i == path.pointCount - 1; + var liniarRightPosition = (nextPoint.position - controlPoint.position) / 3f; + var isRightTangentLinear = isRightEndpoint || (controlPoint.localRightTangent - liniarRightPosition).sqrMagnitude < kEpsilon; + + if (isRightTangentLinear) + controlPoint.localRightTangent = Vector3.zero; + + if (isLeftTangentLinear && isRightTangentLinear) + controlPoint.tangentMode = TangentMode.Linear; + } + else if (controlPoint.tangentMode == TangentMode.Continuous) + { + //TODO: ensure tangent continuity + } + + controlPoint.StoreTangents(); + path.SetPoint(i, controlPoint); + } + + path.localToWorldMatrix = localToWorldMatrix; + } + + public static void SetTangentMode(this IEditablePath path, int index, TangentMode tangentMode) + { + var localToWorldMatrix = path.localToWorldMatrix; + path.localToWorldMatrix = Matrix4x4.identity; + + var controlPoint = path.GetPoint(index); + var isEndpoint = path.isOpenEnded && (index == 0 || index == path.pointCount - 1); + var oldTangentMode = controlPoint.tangentMode; + + controlPoint.tangentMode = tangentMode; + controlPoint.RestoreTangents(); + + if (tangentMode == TangentMode.Linear) + { + controlPoint.localLeftTangent = Vector3.zero; + controlPoint.localRightTangent = Vector3.zero; + } + else if (tangentMode == TangentMode.Continuous && !isEndpoint) + { + var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero; + var isRightLinear = controlPoint.localRightTangent == Vector3.zero; + var tangentDotProduct = Vector3.Dot(controlPoint.localLeftTangent.normalized, controlPoint.localRightTangent.normalized); + var isContinous = tangentDotProduct < 0f && (tangentDotProduct + 1) < 0.001f; + var isLinear = isLeftLinear && isRightLinear; + + if ((isLinear || oldTangentMode == TangentMode.Broken) && !isContinous) + { + var prevPoint = path.GetPrevPoint(index); + var nextPoint = path.GetNextPoint(index); + var vLeft = prevPoint.position - controlPoint.position; + var vRight = nextPoint.position - controlPoint.position; + var rightDirection = Vector3.Cross(Vector3.Cross(vLeft, vRight), vLeft.normalized + vRight.normalized).normalized; + var scale = 1f / 3f; + + if (isLeftLinear) + controlPoint.localLeftTangent = vLeft.magnitude * scale * -rightDirection; + else + controlPoint.localLeftTangent = controlPoint.localLeftTangent.magnitude * -rightDirection; + + if (isRightLinear) + controlPoint.localRightTangent = vRight.magnitude * scale * rightDirection; + else + controlPoint.localRightTangent = controlPoint.localRightTangent.magnitude * rightDirection; + } + } + else + { + var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero; + var isRightLinear = controlPoint.localRightTangent == Vector3.zero; + + if (isLeftLinear || isRightLinear) + { + if (isLeftLinear) + controlPoint.localLeftTangent = path.CalculateLocalLeftTangent(index); + + if (isRightLinear) + controlPoint.localRightTangent = path.CalculateLocalRightTangent(index); + } + } + + controlPoint.StoreTangents(); + path.SetPoint(index, controlPoint); + path.localToWorldMatrix = localToWorldMatrix; + } + + public static void MirrorTangent(this IEditablePath path, int index) + { + var localToWorldMatrix = path.localToWorldMatrix; + path.localToWorldMatrix = Matrix4x4.identity; + + var controlPoint = path.GetPoint(index); + + if (controlPoint.tangentMode == TangentMode.Linear) + return; + + if (!Mathf.Approximately((controlPoint.localLeftTangent + controlPoint.localRightTangent).sqrMagnitude, 0f)) + { + if (controlPoint.mirrorLeft) + controlPoint.localLeftTangent = -controlPoint.localRightTangent; + else + controlPoint.localRightTangent = -controlPoint.localLeftTangent; + + controlPoint.StoreTangents(); + path.SetPoint(index, controlPoint); + } + + path.localToWorldMatrix = localToWorldMatrix; + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs.meta b/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs.meta index 98cfc27..a59349e 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePathExtensions.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 3929c9175115ab54d8b464a5d88f880d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 3929c9175115ab54d8b464a5d88f880d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs b/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs index 9fc76b8..15f5b0e 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs @@ -1,14 +1,14 @@ -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class EditablePathUtility - { - public static int Mod(int x, int m) - { - int r = x % m; - return r < 0 ? r + m : r; - } - } -} +using UnityEngine; +using UnityEditor; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class EditablePathUtility + { + public static int Mod(int x, int m) + { + int r = x % m; + return r < 0 ? r + m : r; + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs.meta b/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs.meta index 478609f..f41856f 100644 --- a/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/EditablePathUtility.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 045b0530f3a77534383bb173e353942e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 045b0530f3a77534383bb173e353942e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs b/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs index 8243e0c..a9b5b99 100644 --- a/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs +++ b/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs @@ -1,24 +1,25 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface IEditablePath : ISelectable - { - ShapeType shapeType { get; set; } - IUndoObject undoObject { get; set; } - ISelection selection { get; } - Matrix4x4 localToWorldMatrix { get; set; } - Vector3 forward { get; set; } - Vector3 up { get; set; } - Vector3 right { get; set; } - bool isOpenEnded { get; set; } - int pointCount { get; } - ControlPoint GetPoint(int index); - void SetPoint(int index, ControlPoint controlPoint); - void AddPoint(ControlPoint controlPoint); - void InsertPoint(int index, ControlPoint controlPoint); - void RemovePoint(int index); - void Clear(); - } -} +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface IEditablePath : ISelectable + { + ShapeType shapeType { get; set; } + IUndoObject undoObject { get; set; } + ISelection selection { get; } + Matrix4x4 localToWorldMatrix { get; set; } + Vector3 forward { get; set; } + Vector3 up { get; set; } + Vector3 right { get; set; } + bool isOpenEnded { get; set; } + int pointCount { get; } + ControlPoint GetPoint(int index); + void SetPoint(int index, ControlPoint controlPoint); + void AddPoint(ControlPoint controlPoint); + void InsertPoint(int index, ControlPoint controlPoint); + void RemovePoint(int index); + void Clear(); + void SetDefaultShape(); + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs.meta b/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs.meta index f0a49cf..5a88979 100644 --- a/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/IEditablePath.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 094bf57853883694a85fea7717b55eb8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 094bf57853883694a85fea7717b55eb8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs b/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs index 4355fc6..ac55aea 100644 --- a/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs +++ b/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs @@ -1,24 +1,24 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface IEditablePathController - { - IEditablePath editablePath { get; set; } - IEditablePath closestEditablePath { get; } - ISnapping snapping { get; set; } - bool enableSnapping { get; set; } - void RegisterUndo(string name); - void ClearSelection(); - void SelectPoint(int index, bool select); - void CreatePoint(int index, Vector3 position); - void RemoveSelectedPoints(); - void MoveSelectedPoints(Vector3 delta); - void MoveEdge(int index, Vector3 delta); - void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent); - void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent); - void ClearClosestPath(); - void AddClosestPath(float distance); - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface IEditablePathController + { + IEditablePath editablePath { get; set; } + IEditablePath closestEditablePath { get; } + ISnapping snapping { get; set; } + bool enableSnapping { get; set; } + void RegisterUndo(string name); + void ClearSelection(); + void SelectPoint(int index, bool select); + void CreatePoint(int index, Vector3 position); + void RemoveSelectedPoints(); + void MoveSelectedPoints(Vector3 delta); + void MoveEdge(int index, Vector3 delta); + void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent); + void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent); + void ClearClosestPath(); + void AddClosestPath(float distance); + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs.meta b/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs.meta index 3051dc6..c5bbf78 100644 --- a/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/IEditablePathController.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 611192c6ef0c17644bcabfd042900ac0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 611192c6ef0c17644bcabfd042900ac0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs b/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs index 6dd1a9e..407bb4c 100644 --- a/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs +++ b/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs @@ -1,10 +1,10 @@ -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface ISnapping - { - T Snap(T value); - } -} +using UnityEngine; +using UnityEditor; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface ISnapping + { + T Snap(T value); + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs.meta b/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs.meta index 96db99d..aa4827b 100644 --- a/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/ISnapping.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 0289f9af7f701f04b8e06f0cb041b85f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 0289f9af7f701f04b8e06f0cb041b85f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs b/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs index 3d9904c..d5c00c6 100644 --- a/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs +++ b/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs @@ -1,9 +1,9 @@ -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface IUndoObject - { - void RegisterUndo(string name); - } -} +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface IUndoObject + { + void RegisterUndo(string name); + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs.meta b/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs.meta index 35397cb..c1320a5 100644 --- a/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/IUndoObject.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 4c2406b0a6c85614f8a800078ec98dc6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 4c2406b0a6c85614f8a800078ec98dc6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs b/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs index 49005a3..adde85e 100644 --- a/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs +++ b/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs @@ -1,153 +1,152 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class MultipleEditablePathController : IEditablePathController - { - private IEditablePathController m_Controller = new EditablePathController(); - private List m_Paths = new List(); - private float m_ClosestDistance = float.MaxValue; - private IEditablePath m_ClosestPath; - - public IEditablePath editablePath - { - get { return m_Controller.editablePath; } - set { m_Controller.editablePath = value; } - } - - public IEditablePath closestEditablePath { get; private set; } - - public ISnapping snapping - { - get { return m_Controller.snapping; } - set { m_Controller.snapping = value; } - } - - public bool enableSnapping - { - get { return m_Controller.enableSnapping; } - set { m_Controller.enableSnapping = value; } - } - - public void ClearPaths() - { - m_Paths.Clear(); - } - - public void AddPath(IEditablePath path) - { - if (!m_Paths.Contains(path)) - m_Paths.Add(path); - } - - public void RemovePath(IEditablePath path) - { - m_Paths.Remove(path); - } - - public void RegisterUndo(string name) - { - var current = editablePath; - - ForEach((s) => - { - editablePath = s; - m_Controller.RegisterUndo(name); - }); - - editablePath = current; - } - - public void ClearSelection() - { - var current = editablePath; - - ForEach((s) => - { - editablePath = s; - m_Controller.ClearSelection(); - }); - - editablePath = current; - } - - public void SelectPoint(int index, bool select) - { - m_Controller.SelectPoint(index, select); - } - - public void CreatePoint(int index, Vector3 position) - { - m_Controller.CreatePoint(index, position); - } - - public void RemoveSelectedPoints() - { - var current = editablePath; - - ForEach((s) => - { - editablePath = s; - m_Controller.RemoveSelectedPoints(); - }); - - editablePath = current; - } - - public void MoveSelectedPoints(Vector3 delta) - { - var current = editablePath; - - ForEach((s) => - { - editablePath = s; - m_Controller.MoveSelectedPoints(delta); - }); - - editablePath = current; - } - - public void MoveEdge(int index, Vector3 delta) - { - m_Controller.MoveEdge(index, delta); - } - - public void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent) - { - m_Controller.SetLeftTangent(index, position, setToLinear, mirror, cachedRightTangent); - } - - public void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent) - { - m_Controller.SetRightTangent(index, position, setToLinear, mirror, cachedLeftTangent); - } - - public void ClearClosestPath() - { - m_ClosestDistance = float.MaxValue; - closestEditablePath = null; - } - - public void AddClosestPath(float distance) - { - if (distance <= m_ClosestDistance) - { - m_ClosestDistance = distance; - closestEditablePath = editablePath; - } - } - - private void ForEach(Action action) - { - foreach(var path in m_Paths) - { - if (path == null) - continue; - - action(path); - } - } - } -} +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class MultipleEditablePathController : IEditablePathController + { + private IEditablePathController m_Controller = new EditablePathController(); + private List m_Paths = new List(); + private float m_ClosestDistance = float.MaxValue; + + public IEditablePath editablePath + { + get { return m_Controller.editablePath; } + set { m_Controller.editablePath = value; } + } + + public IEditablePath closestEditablePath { get; private set; } + + public ISnapping snapping + { + get { return m_Controller.snapping; } + set { m_Controller.snapping = value; } + } + + public bool enableSnapping + { + get { return m_Controller.enableSnapping; } + set { m_Controller.enableSnapping = value; } + } + + public void ClearPaths() + { + m_Paths.Clear(); + } + + public void AddPath(IEditablePath path) + { + if (!m_Paths.Contains(path)) + m_Paths.Add(path); + } + + public void RemovePath(IEditablePath path) + { + m_Paths.Remove(path); + } + + public void RegisterUndo(string name) + { + var current = editablePath; + + ForEach((s) => + { + editablePath = s; + m_Controller.RegisterUndo(name); + }); + + editablePath = current; + } + + public void ClearSelection() + { + var current = editablePath; + + ForEach((s) => + { + editablePath = s; + m_Controller.ClearSelection(); + }); + + editablePath = current; + } + + public void SelectPoint(int index, bool select) + { + m_Controller.SelectPoint(index, select); + } + + public void CreatePoint(int index, Vector3 position) + { + m_Controller.CreatePoint(index, position); + } + + public void RemoveSelectedPoints() + { + var current = editablePath; + + ForEach((s) => + { + editablePath = s; + m_Controller.RemoveSelectedPoints(); + }); + + editablePath = current; + } + + public void MoveSelectedPoints(Vector3 delta) + { + var current = editablePath; + + ForEach((s) => + { + editablePath = s; + m_Controller.MoveSelectedPoints(delta); + }); + + editablePath = current; + } + + public void MoveEdge(int index, Vector3 delta) + { + m_Controller.MoveEdge(index, delta); + } + + public void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent) + { + m_Controller.SetLeftTangent(index, position, setToLinear, mirror, cachedRightTangent); + } + + public void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent) + { + m_Controller.SetRightTangent(index, position, setToLinear, mirror, cachedLeftTangent); + } + + public void ClearClosestPath() + { + m_ClosestDistance = float.MaxValue; + closestEditablePath = null; + } + + public void AddClosestPath(float distance) + { + if (distance <= m_ClosestDistance) + { + m_ClosestDistance = distance; + closestEditablePath = editablePath; + } + } + + private void ForEach(Action action) + { + foreach (var path in m_Paths) + { + if (path == null) + continue; + + action(path); + } + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs.meta b/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs.meta index 0cd3b59..bc288c4 100644 --- a/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/MultipleEditablePathController.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 809b66587caf61f4eb4ebf2a3fe2a17b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 809b66587caf61f4eb4ebf2a3fe2a17b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditablePath/Snapping.cs b/Editor/2D/ShapeEditor/EditablePath/Snapping.cs index 569280a..a9e62a0 100644 --- a/Editor/2D/ShapeEditor/EditablePath/Snapping.cs +++ b/Editor/2D/ShapeEditor/EditablePath/Snapping.cs @@ -1,21 +1,21 @@ -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class Snapping : ISnapping - { - public Vector3 Snap(Vector3 position) - { - return new Vector3( - Snap(position.x, EditorPrefs.GetFloat("MoveSnapX", 1f)), - Snap(position.y, EditorPrefs.GetFloat("MoveSnapY", 1f)), - position.z); - } - - private float Snap(float value, float snap) - { - return Mathf.Round(value / snap) * snap; - } - } -} +using UnityEngine; +using UnityEditor; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class Snapping : ISnapping + { + public Vector3 Snap(Vector3 position) + { + return new Vector3( + Snap(position.x, EditorPrefs.GetFloat("MoveSnapX", 1f)), + Snap(position.y, EditorPrefs.GetFloat("MoveSnapY", 1f)), + position.z); + } + + private float Snap(float value, float snap) + { + return Mathf.Round(value / snap) * snap; + } + } +} diff --git a/Editor/2D/ShapeEditor/EditablePath/Snapping.cs.meta b/Editor/2D/ShapeEditor/EditablePath/Snapping.cs.meta index bea0aa2..5290811 100644 --- a/Editor/2D/ShapeEditor/EditablePath/Snapping.cs.meta +++ b/Editor/2D/ShapeEditor/EditablePath/Snapping.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 98450075dc073964db01f90b7a192857 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 98450075dc073964db01f90b7a192857 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool.meta b/Editor/2D/ShapeEditor/EditorTool.meta index 37c7051..f896f54 100644 --- a/Editor/2D/ShapeEditor/EditorTool.meta +++ b/Editor/2D/ShapeEditor/EditorTool.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 855fcc903225be64da127bc5c0479551 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 855fcc903225be64da127bc5c0479551 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs index 843ee49..d8ecf4e 100644 --- a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs +++ b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs @@ -1,72 +1,72 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class GenericScriptablePath : ScriptablePath - { - [SerializeField] - private List m_Data = new List(); - - public T[] data - { - get { return m_Data.ToArray(); } - set - { - if (value.Length != pointCount) - throw new Exception("Custom data count does not match control point count"); - - m_Data.Clear(); - m_Data.AddRange(value); - } - } - - public override void Clear() - { - base.Clear(); - - m_Data.Clear(); - } - - public override void AddPoint(ControlPoint controlPoint) - { - base.AddPoint(controlPoint); - - m_Data.Add(Create()); - } - - public override void InsertPoint(int index, ControlPoint controlPoint) - { - base.InsertPoint(index, controlPoint); - - m_Data.Insert(index, Create()); - } - - public override void RemovePoint(int index) - { - base.RemovePoint(index); - - Destroy(m_Data[index]); - - m_Data.RemoveAt(index); - } - - public T GetData(int index) - { - return m_Data[index]; - } - - public void SetData(int index, T data) - { - m_Data[index] = data; - } - - protected virtual T Create() - { - return Activator.CreateInstance(); - } - - protected virtual void Destroy(T data) { } - } -} \ No newline at end of file +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class GenericScriptablePath : ScriptablePath + { + [SerializeField] + private List m_Data = new List(); + + public T[] data + { + get { return m_Data.ToArray(); } + set + { + if (value.Length != pointCount) + throw new Exception("Custom data count does not match control point count"); + + m_Data.Clear(); + m_Data.AddRange(value); + } + } + + public override void Clear() + { + base.Clear(); + + m_Data.Clear(); + } + + public override void AddPoint(ControlPoint controlPoint) + { + base.AddPoint(controlPoint); + + m_Data.Add(Create()); + } + + public override void InsertPoint(int index, ControlPoint controlPoint) + { + base.InsertPoint(index, controlPoint); + + m_Data.Insert(index, Create()); + } + + public override void RemovePoint(int index) + { + base.RemovePoint(index); + + Destroy(m_Data[index]); + + m_Data.RemoveAt(index); + } + + public T GetData(int index) + { + return m_Data[index]; + } + + public void SetData(int index, T data) + { + m_Data[index] = data; + } + + protected virtual T Create() + { + return Activator.CreateInstance(); + } + + protected virtual void Destroy(T data) { } + } +} diff --git a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs.meta b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs.meta index 5377c74..309fe5e 100644 --- a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePath.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: e92b578055f69f847a7479e6699b6dd9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e92b578055f69f847a7479e6699b6dd9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs index a4421f6..65afd40 100644 --- a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs +++ b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs @@ -1,120 +1,120 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.EditorTools; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class GenericScriptablePathInspector : ScriptablePathInspector where U : ScriptableData - { - private List m_DataObjects = new List(); - private List m_SelectedDataObjects = new List(); - private Editor m_CachedEditor = null; - - private void OnEnable() - { - PrepareDataObjects(); - } - - private void OnDestroy() - { - DestroyDataObjects(); - } - - public override void OnInspectorGUI() - { - base.OnInspectorGUI(); - - DoCustomDataInspector(); - } - - protected void DoCustomDataInspector() - { - PrepareDataObjects(); - - if (m_SelectedDataObjects.Count > 0) - { - CreateCachedEditor(m_SelectedDataObjects.ToArray(), null, ref m_CachedEditor); - - EditorGUI.BeginChangeCheck(); - - m_CachedEditor.OnInspectorGUI(); - - if (EditorGUI.EndChangeCheck()) - SetDataObjects(); - } - } - - private void PrepareDataObjects() - { - var elementCount = 0; - - m_SelectedDataObjects.Clear(); - - foreach(var path in paths) - elementCount += path.pointCount; - - while (m_DataObjects.Count < elementCount) - CreateDataObject(); - - var index = 0; - foreach(var path in paths) - { - var genericPath = path as GenericScriptablePath; - var customDataArray = genericPath.data; - var length = customDataArray.Length; - - for (var i = 0; i < length; ++i) - { - var dataObject = m_DataObjects[index + i]; - dataObject.data = customDataArray[i]; - - if (path.selection.Contains(i)) - { - dataObject.owner = path.owner; - dataObject.index = i; - m_SelectedDataObjects.Add(dataObject); - } - } - - index += length; - } - } - - private void SetDataObjects() - { - var index = 0; - foreach(var path in paths) - { - var genericPath = path as GenericScriptablePath; - var customDataArray = genericPath.data; - var length = customDataArray.Length; - - for (var i = 0; i < length; ++i) - customDataArray[i] = m_DataObjects[index + i].data; - - genericPath.data = customDataArray; - - index += length; - } - } - - private U CreateDataObject() - { - var dataObject = ScriptableObject.CreateInstance(); - m_DataObjects.Add(dataObject); - return dataObject; - } - - private void DestroyDataObjects() - { - foreach (var customDataObject in m_DataObjects) - DestroyImmediate(customDataObject); - - m_DataObjects.Clear(); - m_SelectedDataObjects.Clear(); - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.EditorTools; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class GenericScriptablePathInspector : ScriptablePathInspector where U : ScriptableData + { + private List m_DataObjects = new List(); + private List m_SelectedDataObjects = new List(); + private Editor m_CachedEditor = null; + + private void OnEnable() + { + PrepareDataObjects(); + } + + private void OnDestroy() + { + DestroyDataObjects(); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + DoCustomDataInspector(); + } + + protected void DoCustomDataInspector() + { + PrepareDataObjects(); + + if (m_SelectedDataObjects.Count > 0) + { + CreateCachedEditor(m_SelectedDataObjects.ToArray(), null, ref m_CachedEditor); + + EditorGUI.BeginChangeCheck(); + + m_CachedEditor.OnInspectorGUI(); + + if (EditorGUI.EndChangeCheck()) + SetDataObjects(); + } + } + + private void PrepareDataObjects() + { + var elementCount = 0; + + m_SelectedDataObjects.Clear(); + + foreach (var path in paths) + elementCount += path.pointCount; + + while (m_DataObjects.Count < elementCount) + CreateDataObject(); + + var index = 0; + foreach (var path in paths) + { + var genericPath = path as GenericScriptablePath; + var customDataArray = genericPath.data; + var length = customDataArray.Length; + + for (var i = 0; i < length; ++i) + { + var dataObject = m_DataObjects[index + i]; + dataObject.data = customDataArray[i]; + + if (path.selection.Contains(i)) + { + dataObject.owner = path.owner; + dataObject.index = i; + m_SelectedDataObjects.Add(dataObject); + } + } + + index += length; + } + } + + private void SetDataObjects() + { + var index = 0; + foreach (var path in paths) + { + var genericPath = path as GenericScriptablePath; + var customDataArray = genericPath.data; + var length = customDataArray.Length; + + for (var i = 0; i < length; ++i) + customDataArray[i] = m_DataObjects[index + i].data; + + genericPath.data = customDataArray; + + index += length; + } + } + + private U CreateDataObject() + { + var dataObject = ScriptableObject.CreateInstance(); + m_DataObjects.Add(dataObject); + return dataObject; + } + + private void DestroyDataObjects() + { + foreach (var customDataObject in m_DataObjects) + DestroyImmediate(customDataObject); + + m_DataObjects.Clear(); + m_SelectedDataObjects.Clear(); + } + } +} diff --git a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs.meta b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs.meta index 06fb0e4..48d037d 100644 --- a/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/GenericScriptablePathInspector.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: ea84bc83d2f9d5f438925b0a86bbbd99 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ea84bc83d2f9d5f438925b0a86bbbd99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs b/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs index 0ae54fd..ccf0835 100644 --- a/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs +++ b/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs @@ -1,121 +1,121 @@ -#pragma warning disable 0618 -using System; -using System.Linq; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.EditorTools; -using UnityEditor.Experimental.Rendering.Universal.Path2D; - -#if !UNITY_2020_2_OR_NEWER -using ToolManager=UnityEditor.EditorTools.EditorTools; -#endif - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal abstract class PathComponentEditor : Editor where T : ScriptablePath - { - private static class Contents - { - public static readonly GUIContent snappingLabel = new GUIContent("Snapping", "Snap points using the snap settings"); - } - - private Editor m_CachedEditor = null; - - protected void DoEditButton(GUIContent icon, string label) where U : PathEditorTool - { - const float kButtonWidth = 33; - const float kButtonHeight = 23; - const float k_SpaceBetweenLabelAndButton = 5; - var buttonStyle = new GUIStyle("EditModeSingleButton"); - - var rect = EditorGUILayout.GetControlRect(true, kButtonHeight, buttonStyle); - var buttonRect = new Rect(rect.xMin + EditorGUIUtility.labelWidth, rect.yMin, kButtonWidth, kButtonHeight); - - var labelContent = new GUIContent(label); - var labelSize = GUI.skin.label.CalcSize(labelContent); - - var labelRect = new Rect( - buttonRect.xMax + k_SpaceBetweenLabelAndButton, - rect.yMin + (rect.height - labelSize.y) * .5f, - labelSize.x, - rect.height); - - using (new EditorGUI.DisabledGroupScope(!EditorToolManager.IsAvailable())) - { - using (var check = new EditorGUI.ChangeCheckScope()) - { - var isActive = GUI.Toggle(buttonRect, EditorToolManager.IsActiveTool(), icon, buttonStyle); - - GUI.Label(labelRect, label); - - if (check.changed) - { - if (isActive) - ToolManager.SetActiveTool(); - else - ToolManager.RestorePreviousTool(); - } - } - } - } - - protected void DoPathInspector() where U : PathEditorTool - { - if (EditorToolManager.IsActiveTool() && EditorToolManager.IsAvailable()) - { - var paths = EditorToolManager.GetEditorTool().paths; - - CreateCachedEditor(paths, null, ref m_CachedEditor); - - if (m_CachedEditor == null) //Needed to avoid a nullref on exiting playmode - return; - - using (var check = new EditorGUI.ChangeCheckScope()) - { - m_CachedEditor.OnInspectorGUI(); - - if (check.changed) - EditorToolManager.GetEditorTool().SetShapes(); - } - } - } - - protected void DoSnappingInspector() where U : PathEditorTool - { - if (EditorToolManager.IsActiveTool() && EditorToolManager.IsAvailable()) - { - var tool = EditorToolManager.GetEditorTool(); - tool.enableSnapping = EditorGUILayout.Toggle(Contents.snappingLabel, tool.enableSnapping); - } - } - - protected void DoOpenEndedInspector(SerializedProperty isOpenEndedProperty) where U : PathEditorTool - { - serializedObject.Update(); - - using (var check = new EditorGUI.ChangeCheckScope()) - { - EditorGUILayout.PropertyField(isOpenEndedProperty); - - if (check.changed) - { - if (EditorToolManager.IsActiveTool() && EditorToolManager.IsAvailable()) - { - var paths = EditorToolManager.GetEditorTool().paths; - - foreach (var path in paths) - { - path.undoObject.RegisterUndo("Set Open Ended"); - path.isOpenEnded = isOpenEndedProperty.boolValue; - } - } - } - } - - serializedObject.ApplyModifiedProperties(); - } - } -} -#pragma warning restore 0618 +#pragma warning disable 0618 +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.EditorTools; +using UnityEditor.Rendering.Universal.Path2D; + +#if !UNITY_2020_2_OR_NEWER +using ToolManager = UnityEditor.EditorTools.EditorTools; +#endif + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal abstract class PathComponentEditor : Editor where T : ScriptablePath + { + private static class Contents + { + public static readonly GUIContent snappingLabel = new GUIContent("Snapping", "Snap points using the snap settings"); + } + + private Editor m_CachedEditor = null; + + protected void DoEditButton(GUIContent icon, string label) where U : PathEditorTool + { + const float kButtonWidth = 33; + const float kButtonHeight = 23; + const float k_SpaceBetweenLabelAndButton = 5; + var buttonStyle = new GUIStyle("EditModeSingleButton"); + + var rect = EditorGUILayout.GetControlRect(true, kButtonHeight, buttonStyle); + var buttonRect = new Rect(rect.xMin + EditorGUIUtility.labelWidth, rect.yMin, kButtonWidth, kButtonHeight); + + var labelContent = new GUIContent(label); + var labelSize = GUI.skin.label.CalcSize(labelContent); + + var labelRect = new Rect( + buttonRect.xMax + k_SpaceBetweenLabelAndButton, + rect.yMin + (rect.height - labelSize.y) * .5f, + labelSize.x, + rect.height); + + using (new EditorGUI.DisabledGroupScope(!EditorToolManager.IsAvailable())) + { + using (var check = new EditorGUI.ChangeCheckScope()) + { + var isActive = GUI.Toggle(buttonRect, EditorToolManager.IsActiveTool(), icon, buttonStyle); + + GUI.Label(labelRect, label); + + if (check.changed) + { + if (isActive) + ToolManager.SetActiveTool(); + else + ToolManager.RestorePreviousTool(); + } + } + } + } + + protected void DoPathInspector() where U : PathEditorTool + { + if (EditorToolManager.IsActiveTool() && EditorToolManager.IsAvailable()) + { + var paths = EditorToolManager.GetEditorTool().paths; + + CreateCachedEditor(paths, null, ref m_CachedEditor); + + if (m_CachedEditor == null) //Needed to avoid a nullref on exiting playmode + return; + + using (var check = new EditorGUI.ChangeCheckScope()) + { + m_CachedEditor.OnInspectorGUI(); + + if (check.changed) + EditorToolManager.GetEditorTool().SetShapes(); + } + } + } + + protected void DoSnappingInspector() where U : PathEditorTool + { + if (EditorToolManager.IsActiveTool() && EditorToolManager.IsAvailable()) + { + var tool = EditorToolManager.GetEditorTool(); + tool.enableSnapping = EditorGUILayout.Toggle(Contents.snappingLabel, tool.enableSnapping); + } + } + + protected void DoOpenEndedInspector(SerializedProperty isOpenEndedProperty) where U : PathEditorTool + { + serializedObject.Update(); + + using (var check = new EditorGUI.ChangeCheckScope()) + { + EditorGUILayout.PropertyField(isOpenEndedProperty); + + if (check.changed) + { + if (EditorToolManager.IsActiveTool() && EditorToolManager.IsAvailable()) + { + var paths = EditorToolManager.GetEditorTool().paths; + + foreach (var path in paths) + { + path.undoObject.RegisterUndo("Set Open Ended"); + path.isOpenEnded = isOpenEndedProperty.boolValue; + } + } + } + } + + serializedObject.ApplyModifiedProperties(); + } + } +} +#pragma warning restore 0618 diff --git a/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs.meta b/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs.meta index 2d05e62..461e360 100644 --- a/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/PathComponentEditor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: a4ffc31437b308d4884c861c73c614f3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: a4ffc31437b308d4884c861c73c614f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs b/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs index 1cf630a..d4e1a24 100644 --- a/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs +++ b/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs @@ -1,499 +1,499 @@ -#pragma warning disable 0618 -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.EditorTools; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; - -using UnityObject = UnityEngine.Object; -#if !UNITY_2020_2_OR_NEWER -using ToolManager=UnityEditor.EditorTools.EditorTools; -#endif - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal static class PathEditorToolContents - { - internal static readonly GUIContent shapeToolIcon = IconContent("ShapeTool", "Start editing the Shape in the Scene View."); - internal static readonly GUIContent shapeToolPro = IconContent("ShapeToolPro", "Start editing the Shape in the Scene View."); - - internal static GUIContent IconContent(string name, string tooltip = null) - { - return new GUIContent(Resources.Load(name), tooltip); - } - - public static GUIContent icon - { - get - { - if (EditorGUIUtility.isProSkin) - return shapeToolPro; - - return shapeToolIcon; - } - } - } - - internal interface IDuringSceneGuiTool - { - void DuringSceneGui(SceneView sceneView); - bool IsAvailable(); - } - - [InitializeOnLoad] - internal class EditorToolManager - { - private static List m_Tools = new List(); - - static EditorToolManager() - { - SceneView.duringSceneGui += DuringSceneGui; - } - - internal static void Add(IDuringSceneGuiTool tool) - { - if (!m_Tools.Contains(tool) && tool is EditorTool) - m_Tools.Add(tool); - } - - internal static void Remove(IDuringSceneGuiTool tool) - { - if (m_Tools.Contains(tool)) - m_Tools.Remove(tool); - } - - internal static bool IsActiveTool() where T : EditorTool - { - return ToolManager.activeToolType.Equals(typeof(T)); - } - - internal static bool IsAvailable() where T : EditorTool - { - var tool = GetEditorTool(); - - if (tool != null) - return tool.IsAvailable(); - - return false; - } - - internal static T GetEditorTool() where T : EditorTool - { - foreach(var tool in m_Tools) - { - if (tool.GetType().Equals(typeof(T))) - return tool as T; - } - - return null; - } - - private static void DuringSceneGui(SceneView sceneView) - { - foreach (var tool in m_Tools) - { - if (tool.IsAvailable() && ToolManager.IsActiveTool(tool as EditorTool)) - tool.DuringSceneGui(sceneView); - } - } - } - - internal abstract class PathEditorTool : EditorTool, IDuringSceneGuiTool where T : ScriptablePath - { - private Dictionary m_Paths = new Dictionary(); - private IGUIState m_GUIState = new GUIState(); - private Dictionary m_GUISystems = new Dictionary(); - private Dictionary m_SerializedObjects = new Dictionary(); - private MultipleEditablePathController m_Controller = new MultipleEditablePathController(); - private PointRectSelector m_RectSelector = new PointRectSelector(); - private bool m_IsActive = false; - - internal T[] paths - { - get { return m_Paths.Values.ToArray(); } - } - - public bool enableSnapping - { - get { return m_Controller.enableSnapping; } - set { m_Controller.enableSnapping = value; } - } - - public override GUIContent toolbarIcon - { - get { return PathEditorToolContents.icon; } - } - - public override bool IsAvailable() - { - return targets.Count() > 0; - } - - public T GetPath(UnityObject targetObject) - { - var path = default(T); - m_Paths.TryGetValue(targetObject, out path); - return path; - } - - public void SetPath(UnityObject target) - { - var path = GetPath(target); - path.localToWorldMatrix = Matrix4x4.identity; - - var undoName = Undo.GetCurrentGroupName(); - var serializedObject = GetSerializedObject(target); - - serializedObject.UpdateIfRequiredOrScript(); - - SetShape(path, serializedObject); - - Undo.SetCurrentGroupName(undoName); - } - - private void RepaintInspectors() - { - var editorWindows = Resources.FindObjectsOfTypeAll(); - - foreach (var editorWindow in editorWindows) - { - if (editorWindow.titleContent.text == "Inspector") - editorWindow.Repaint(); - } - } - - private void OnEnable() - { - m_IsActive = false; - EditorToolManager.Add(this); - - SetupRectSelector(); - HandleActivation(); - - ToolManager.activeToolChanged += HandleActivation; - } - - private void OnDestroy() - { - EditorToolManager.Remove(this); - - ToolManager.activeToolChanged -= HandleActivation; - UnregisterCallbacks(); - } - - private void HandleActivation() - { - if (m_IsActive == false && ToolManager.IsActiveTool(this)) - Activate(); - else if (m_IsActive) - Deactivate(); - } - - private void Activate() - { - m_IsActive = true; - RegisterCallbacks(); - InitializeCache(); - OnActivate(); - } - - private void Deactivate() - { - OnDeactivate(); - DestroyCache(); - UnregisterCallbacks(); - m_IsActive = false; - } - - private void RegisterCallbacks() - { - UnregisterCallbacks(); - Selection.selectionChanged += SelectionChanged; - EditorApplication.playModeStateChanged += PlayModeStateChanged; - Undo.undoRedoPerformed += UndoRedoPerformed; - } - - private void UnregisterCallbacks() - { - Selection.selectionChanged -= SelectionChanged; - EditorApplication.playModeStateChanged -= PlayModeStateChanged; - Undo.undoRedoPerformed -= UndoRedoPerformed; - } - - private void DestroyCache() - { - foreach (var pair in m_Paths) - { - var path = pair.Value; - - if (path != null) - { - Undo.ClearUndo(path); - UnityObject.DestroyImmediate(path); - } - } - m_Paths.Clear(); - m_Controller.ClearPaths(); - m_GUISystems.Clear(); - m_SerializedObjects.Clear(); - } - - private void UndoRedoPerformed() - { - ForEachTarget((target) => - { - var path = GetPath(target); - - if (!path.modified) - InitializePath(target); - }); - } - - private void SelectionChanged() - { - InitializeCache(); - } - - private void PlayModeStateChanged(PlayModeStateChange stateChange) - { - if (stateChange == PlayModeStateChange.EnteredEditMode) - EditorApplication.delayCall += () => { InitializeCache(); }; //HACK: At this point target is null. Let's wait to next frame to refresh. - } - - private void SetupRectSelector() - { - m_RectSelector.onSelectionBegin = BeginSelection; - m_RectSelector.onSelectionChanged = UpdateSelection; - m_RectSelector.onSelectionEnd = EndSelection; - } - - private void ForEachTarget(Action action) - { - foreach(var target in targets) - { - if (target == null) - continue; - - action(target); - } - } - - private void InitializeCache() - { - m_Controller.ClearPaths(); - - ForEachTarget((target) => - { - var path = GetOrCreatePath(target); - var pointCount = path.pointCount; - - InitializePath(target); - - if (pointCount != path.pointCount) - path.selection.Clear(); - - CreateGUISystem(target); - - m_Controller.AddPath(path); - }); - } - - private void InitializePath(UnityObject target) - { - IShape shape = null; - ControlPoint[] controlPoints = null; - - try - { - shape = GetShape(target); - controlPoints = shape.ToControlPoints(); - } - catch (Exception e) - { - Debug.LogError(e.Message); - } - - var path = GetPath(target); - path.Clear(); - - if (shape != null && controlPoints != null) - { - path.localToWorldMatrix = Matrix4x4.identity; - path.shapeType = shape.type; - path.isOpenEnded = shape.isOpenEnded; - - foreach (var controlPoint in controlPoints) - path.AddPoint(controlPoint); - } - - Initialize(path, GetSerializedObject(target)); - } - - private T GetOrCreatePath(UnityObject targetObject) - { - var path = GetPath(targetObject); - - if (path == null) - { - path = ScriptableObject.CreateInstance(); - path.owner = targetObject; - m_Paths[targetObject] = path; - } - - return path; - } - - private GUISystem GetGUISystem(UnityObject target) - { - GUISystem guiSystem; - m_GUISystems.TryGetValue(target, out guiSystem); - return guiSystem; - } - - private void CreateGUISystem(UnityObject target) - { - var guiSystem = new GUISystem(m_GUIState); - var view = new EditablePathView(); - - view.controller = m_Controller; - view.Install(guiSystem); - - m_GUISystems[target] = guiSystem; - } - - private SerializedObject GetSerializedObject(UnityObject target) - { - var serializedObject = default(SerializedObject); - - if (!m_SerializedObjects.TryGetValue(target, out serializedObject)) - { - serializedObject = new SerializedObject(target); - m_SerializedObjects[target] = serializedObject; - } - - return serializedObject; - } - - void IDuringSceneGuiTool.DuringSceneGui(SceneView sceneView) - { - if (m_GUIState.eventType == EventType.Layout) - m_Controller.ClearClosestPath(); - - m_RectSelector.OnGUI(); - - bool changed = false; - - ForEachTarget((target) => - { - var path = GetPath(target); - - if (path != null) - { - path.localToWorldMatrix = GetLocalToWorldMatrix(target); - path.forward = GetForward(target); - path.up = GetUp(target); - path.right = GetRight(target); - m_Controller.editablePath = path; - - using (var check = new EditorGUI.ChangeCheckScope()) - { - GetGUISystem(target).OnGUI(); - OnCustomGUI(path); - changed |= check.changed; - } - } - }); - - if (changed) - { - SetShapes(); - RepaintInspectors(); - } - } - - private void BeginSelection(ISelector selector, bool isAdditive) - { - m_Controller.RegisterUndo("Selection"); - - if (isAdditive) - { - ForEachTarget((target) => - { - var path = GetPath(target); - path.selection.BeginSelection(); - }); - } - else - { - UpdateSelection(selector); - } - } - - private void UpdateSelection(ISelector selector) - { - var repaintInspectors = false; - - ForEachTarget((target) => - { - var path = GetPath(target); - - repaintInspectors |= path.Select(selector); - }); - - if (repaintInspectors) - RepaintInspectors(); - } - - private void EndSelection(ISelector selector) - { - ForEachTarget((target) => - { - var path = GetPath(target); - path.selection.EndSelection(true); - }); - } - - internal void SetShapes() - { - ForEachTarget((target) => - { - SetPath(target); - }); - } - - private Transform GetTransform(UnityObject target) - { - return (target as Component).transform; - } - - private Matrix4x4 GetLocalToWorldMatrix(UnityObject target) - { - return GetTransform(target).localToWorldMatrix; - } - - private Vector3 GetForward(UnityObject target) - { - return GetTransform(target).forward; - } - - private Vector3 GetUp(UnityObject target) - { - return GetTransform(target).up; - } - - private Vector3 GetRight(UnityObject target) - { - return GetTransform(target).right; - } - - protected abstract IShape GetShape(UnityObject target); - protected virtual void Initialize(T path, SerializedObject serializedObject) { } - protected abstract void SetShape(T path, SerializedObject serializedObject); - protected virtual void OnActivate() { } - protected virtual void OnDeactivate() { } - protected virtual void OnCustomGUI(T path) { } - } -} -#pragma warning restore 0618 +#pragma warning disable 0618 +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.EditorTools; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; + +using UnityObject = UnityEngine.Object; +#if !UNITY_2020_2_OR_NEWER +using ToolManager = UnityEditor.EditorTools.EditorTools; +#endif + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal static class PathEditorToolContents + { + internal static readonly GUIContent shapeToolIcon = IconContent("ShapeTool", "Unlocks the shape to allow editing in the Scene View."); + internal static readonly GUIContent shapeToolPro = IconContent("ShapeToolPro", "Unlocks the shape to allow editing in the Scene View."); + + internal static GUIContent IconContent(string name, string tooltip = null) + { + return new GUIContent(Resources.Load(name), tooltip); + } + + public static GUIContent icon + { + get + { + if (EditorGUIUtility.isProSkin) + return shapeToolPro; + + return shapeToolIcon; + } + } + } + + internal interface IDuringSceneGuiTool + { + void DuringSceneGui(SceneView sceneView); + bool IsAvailable(); + } + + [InitializeOnLoad] + internal class EditorToolManager + { + private static List m_Tools = new List(); + + static EditorToolManager() + { + SceneView.duringSceneGui += DuringSceneGui; + } + + internal static void Add(IDuringSceneGuiTool tool) + { + if (!m_Tools.Contains(tool) && tool is EditorTool) + m_Tools.Add(tool); + } + + internal static void Remove(IDuringSceneGuiTool tool) + { + if (m_Tools.Contains(tool)) + m_Tools.Remove(tool); + } + + internal static bool IsActiveTool() where T : EditorTool + { + return ToolManager.activeToolType.Equals(typeof(T)); + } + + internal static bool IsAvailable() where T : EditorTool + { + var tool = GetEditorTool(); + + if (tool != null) + return tool.IsAvailable(); + + return false; + } + + internal static T GetEditorTool() where T : EditorTool + { + foreach (var tool in m_Tools) + { + if (tool.GetType().Equals(typeof(T))) + return tool as T; + } + + return null; + } + + private static void DuringSceneGui(SceneView sceneView) + { + foreach (var tool in m_Tools) + { + if (tool.IsAvailable() && ToolManager.IsActiveTool(tool as EditorTool)) + tool.DuringSceneGui(sceneView); + } + } + } + + internal abstract class PathEditorTool : EditorTool, IDuringSceneGuiTool where T : ScriptablePath + { + private Dictionary m_Paths = new Dictionary(); + private IGUIState m_GUIState = new GUIState(); + private Dictionary m_GUISystems = new Dictionary(); + private Dictionary m_SerializedObjects = new Dictionary(); + private MultipleEditablePathController m_Controller = new MultipleEditablePathController(); + private PointRectSelector m_RectSelector = new PointRectSelector(); + private bool m_IsActive = false; + + internal T[] paths + { + get { return m_Paths.Values.ToArray(); } + } + + public bool enableSnapping + { + get { return m_Controller.enableSnapping; } + set { m_Controller.enableSnapping = value; } + } + + public override GUIContent toolbarIcon + { + get { return PathEditorToolContents.icon; } + } + + public override bool IsAvailable() + { + return targets.Count() > 0; + } + + public T GetPath(UnityObject targetObject) + { + var path = default(T); + m_Paths.TryGetValue(targetObject, out path); + return path; + } + + public void SetPath(UnityObject target) + { + var path = GetPath(target); + path.localToWorldMatrix = Matrix4x4.identity; + + var undoName = Undo.GetCurrentGroupName(); + var serializedObject = GetSerializedObject(target); + + serializedObject.UpdateIfRequiredOrScript(); + + SetShape(path, serializedObject); + + Undo.SetCurrentGroupName(undoName); + } + + private void RepaintInspectors() + { + var editorWindows = Resources.FindObjectsOfTypeAll(); + + foreach (var editorWindow in editorWindows) + { + if (editorWindow.titleContent.text == "Inspector") + editorWindow.Repaint(); + } + } + + private void OnEnable() + { + m_IsActive = false; + EditorToolManager.Add(this); + + SetupRectSelector(); + HandleActivation(); + + ToolManager.activeToolChanged += HandleActivation; + } + + private void OnDestroy() + { + EditorToolManager.Remove(this); + + ToolManager.activeToolChanged -= HandleActivation; + UnregisterCallbacks(); + } + + private void HandleActivation() + { + if (m_IsActive == false && ToolManager.IsActiveTool(this)) + Activate(); + else if (m_IsActive) + Deactivate(); + } + + private void Activate() + { + m_IsActive = true; + RegisterCallbacks(); + InitializeCache(); + OnActivate(); + } + + private void Deactivate() + { + OnDeactivate(); + DestroyCache(); + UnregisterCallbacks(); + m_IsActive = false; + } + + private void RegisterCallbacks() + { + UnregisterCallbacks(); + Selection.selectionChanged += SelectionChanged; + EditorApplication.playModeStateChanged += PlayModeStateChanged; + Undo.undoRedoPerformed += UndoRedoPerformed; + } + + private void UnregisterCallbacks() + { + Selection.selectionChanged -= SelectionChanged; + EditorApplication.playModeStateChanged -= PlayModeStateChanged; + Undo.undoRedoPerformed -= UndoRedoPerformed; + } + + private void DestroyCache() + { + foreach (var pair in m_Paths) + { + var path = pair.Value; + + if (path != null) + { + Undo.ClearUndo(path); + UnityObject.DestroyImmediate(path); + } + } + m_Paths.Clear(); + m_Controller.ClearPaths(); + m_GUISystems.Clear(); + m_SerializedObjects.Clear(); + } + + private void UndoRedoPerformed() + { + ForEachTarget((target) => + { + var path = GetPath(target); + + if (!path.modified) + InitializePath(target); + }); + } + + private void SelectionChanged() + { + InitializeCache(); + } + + private void PlayModeStateChanged(PlayModeStateChange stateChange) + { + if (stateChange == PlayModeStateChange.EnteredEditMode) + EditorApplication.delayCall += () => { InitializeCache(); }; //HACK: At this point target is null. Let's wait to next frame to refresh. + } + + private void SetupRectSelector() + { + m_RectSelector.onSelectionBegin = BeginSelection; + m_RectSelector.onSelectionChanged = UpdateSelection; + m_RectSelector.onSelectionEnd = EndSelection; + } + + private void ForEachTarget(Action action) + { + foreach (var target in targets) + { + if (target == null) + continue; + + action(target); + } + } + + private void InitializeCache() + { + m_Controller.ClearPaths(); + + ForEachTarget((target) => + { + var path = GetOrCreatePath(target); + var pointCount = path.pointCount; + + InitializePath(target); + + if (pointCount != path.pointCount) + path.selection.Clear(); + + CreateGUISystem(target); + + m_Controller.AddPath(path); + }); + } + + private void InitializePath(UnityObject target) + { + IShape shape = null; + ControlPoint[] controlPoints = null; + + try + { + shape = GetShape(target); + controlPoints = shape.ToControlPoints(); + } + catch (Exception e) + { + Debug.LogError(e.Message); + } + + var path = GetPath(target); + path.Clear(); + + if (shape != null && controlPoints != null) + { + path.localToWorldMatrix = Matrix4x4.identity; + path.shapeType = shape.type; + path.isOpenEnded = shape.isOpenEnded; + + foreach (var controlPoint in controlPoints) + path.AddPoint(controlPoint); + } + + Initialize(path, GetSerializedObject(target)); + } + + private T GetOrCreatePath(UnityObject targetObject) + { + var path = GetPath(targetObject); + + if (path == null) + { + path = ScriptableObject.CreateInstance(); + path.owner = targetObject; + m_Paths[targetObject] = path; + } + + return path; + } + + private GUISystem GetGUISystem(UnityObject target) + { + GUISystem guiSystem; + m_GUISystems.TryGetValue(target, out guiSystem); + return guiSystem; + } + + private void CreateGUISystem(UnityObject target) + { + var guiSystem = new GUISystem(m_GUIState); + var view = new EditablePathView(); + + view.controller = m_Controller; + view.Install(guiSystem); + + m_GUISystems[target] = guiSystem; + } + + private SerializedObject GetSerializedObject(UnityObject target) + { + var serializedObject = default(SerializedObject); + + if (!m_SerializedObjects.TryGetValue(target, out serializedObject)) + { + serializedObject = new SerializedObject(target); + m_SerializedObjects[target] = serializedObject; + } + + return serializedObject; + } + + void IDuringSceneGuiTool.DuringSceneGui(SceneView sceneView) + { + if (m_GUIState.eventType == EventType.Layout) + m_Controller.ClearClosestPath(); + + m_RectSelector.OnGUI(); + + bool changed = false; + + ForEachTarget((target) => + { + var path = GetPath(target); + + if (path != null) + { + path.localToWorldMatrix = GetLocalToWorldMatrix(target); + path.forward = GetForward(target); + path.up = GetUp(target); + path.right = GetRight(target); + m_Controller.editablePath = path; + + using (var check = new EditorGUI.ChangeCheckScope()) + { + GetGUISystem(target).OnGUI(); + OnCustomGUI(path); + changed |= check.changed; + } + } + }); + + if (changed) + { + SetShapes(); + RepaintInspectors(); + } + } + + private void BeginSelection(ISelector selector, bool isAdditive) + { + m_Controller.RegisterUndo("Selection"); + + if (isAdditive) + { + ForEachTarget((target) => + { + var path = GetPath(target); + path.selection.BeginSelection(); + }); + } + else + { + UpdateSelection(selector); + } + } + + private void UpdateSelection(ISelector selector) + { + var repaintInspectors = false; + + ForEachTarget((target) => + { + var path = GetPath(target); + + repaintInspectors |= path.Select(selector); + }); + + if (repaintInspectors) + RepaintInspectors(); + } + + private void EndSelection(ISelector selector) + { + ForEachTarget((target) => + { + var path = GetPath(target); + path.selection.EndSelection(true); + }); + } + + internal void SetShapes() + { + ForEachTarget((target) => + { + SetPath(target); + }); + } + + private Transform GetTransform(UnityObject target) + { + return (target as Component).transform; + } + + private Matrix4x4 GetLocalToWorldMatrix(UnityObject target) + { + return GetTransform(target).localToWorldMatrix; + } + + private Vector3 GetForward(UnityObject target) + { + return GetTransform(target).forward; + } + + private Vector3 GetUp(UnityObject target) + { + return GetTransform(target).up; + } + + private Vector3 GetRight(UnityObject target) + { + return GetTransform(target).right; + } + + protected abstract IShape GetShape(UnityObject target); + protected virtual void Initialize(T path, SerializedObject serializedObject) { } + protected abstract void SetShape(T path, SerializedObject serializedObject); + protected virtual void OnActivate() { } + protected virtual void OnDeactivate() { } + protected virtual void OnCustomGUI(T path) { } + } +} +#pragma warning restore 0618 diff --git a/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs.meta b/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs.meta index 14b537d..1c8d2d6 100644 --- a/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/PathEditorTool.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: b6c87eddefd506c43835a1656d08e2ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b6c87eddefd506c43835a1656d08e2ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs b/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs index eab48c3..445326f 100644 --- a/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs +++ b/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs @@ -1,108 +1,107 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.EditorTools; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; -using UnityObject = UnityEngine.Object; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal static class PathEditorToolExtensions - { - public static void CycleTangentMode(this PathEditorTool pathEditorTool) where T : ScriptablePath - { - var first = true; - var mixed = false; - var tangentMode = TangentMode.Linear; - var targets = pathEditorTool.targets; - - foreach(var target in targets) - { - var path = pathEditorTool.GetPath(target); - - if (path.selection.Count == 0) - continue; - - for (var i = 0; i < path.pointCount; ++i) - { - if (!path.selection.Contains(i)) - continue; - - var point = path.GetPoint(i); - - if (first) - { - first = false; - tangentMode = point.tangentMode; - } - else if (point.tangentMode != tangentMode) - { - mixed = true; - break; - } - } - - if (mixed) - break; - } - - if (mixed) - tangentMode = TangentMode.Linear; - else - tangentMode = GetNextTangentMode(tangentMode); - - foreach(var target in targets) - { - var path = pathEditorTool.GetPath(target); - - if (path.selection.Count == 0) - continue; - - path.undoObject.RegisterUndo("Cycle Tangent Mode"); - - for (var i = 0; i < path.pointCount; ++i) - { - if (!path.selection.Contains(i)) - continue; - - path.SetTangentMode(i, tangentMode); - } - - pathEditorTool.SetPath(target); - } - } - - public static void MirrorTangent(this PathEditorTool pathEditorTool) where T : ScriptablePath - { - var targets = pathEditorTool.targets; - - foreach(var target in targets) - { - var path = pathEditorTool.GetPath(target); - - if (path.selection.Count == 0) - continue; - - path.undoObject.RegisterUndo("Mirror Tangents"); - - for (var i = 0; i < path.pointCount; ++i) - { - if (!path.selection.Contains(i)) - continue; - - path.MirrorTangent(i); - } - - pathEditorTool.SetPath(target); - } - } - - private static TangentMode GetNextTangentMode(TangentMode tangentMode) - { - return (TangentMode)((((int)tangentMode) + 1) % Enum.GetValues(typeof(TangentMode)).Length); - } - } - -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.EditorTools; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; +using UnityObject = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal static class PathEditorToolExtensions + { + public static void CycleTangentMode(this PathEditorTool pathEditorTool) where T : ScriptablePath + { + var first = true; + var mixed = false; + var tangentMode = TangentMode.Linear; + var targets = pathEditorTool.targets; + + foreach (var target in targets) + { + var path = pathEditorTool.GetPath(target); + + if (path.selection.Count == 0) + continue; + + for (var i = 0; i < path.pointCount; ++i) + { + if (!path.selection.Contains(i)) + continue; + + var point = path.GetPoint(i); + + if (first) + { + first = false; + tangentMode = point.tangentMode; + } + else if (point.tangentMode != tangentMode) + { + mixed = true; + break; + } + } + + if (mixed) + break; + } + + if (mixed) + tangentMode = TangentMode.Linear; + else + tangentMode = GetNextTangentMode(tangentMode); + + foreach (var target in targets) + { + var path = pathEditorTool.GetPath(target); + + if (path.selection.Count == 0) + continue; + + path.undoObject.RegisterUndo("Cycle Tangent Mode"); + + for (var i = 0; i < path.pointCount; ++i) + { + if (!path.selection.Contains(i)) + continue; + + path.SetTangentMode(i, tangentMode); + } + + pathEditorTool.SetPath(target); + } + } + + public static void MirrorTangent(this PathEditorTool pathEditorTool) where T : ScriptablePath + { + var targets = pathEditorTool.targets; + + foreach (var target in targets) + { + var path = pathEditorTool.GetPath(target); + + if (path.selection.Count == 0) + continue; + + path.undoObject.RegisterUndo("Mirror Tangents"); + + for (var i = 0; i < path.pointCount; ++i) + { + if (!path.selection.Contains(i)) + continue; + + path.MirrorTangent(i); + } + + pathEditorTool.SetPath(target); + } + } + + private static TangentMode GetNextTangentMode(TangentMode tangentMode) + { + return (TangentMode)((((int)tangentMode) + 1) % Enum.GetValues(typeof(TangentMode)).Length); + } + } +} diff --git a/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs.meta b/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs.meta index 96553d2..d9d7a3f 100644 --- a/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/PathEditorToolExtensions.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 92997a15a3ecd6b4ba235b023d6df589 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 92997a15a3ecd6b4ba235b023d6df589 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs b/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs index 27f5275..3db5c76 100644 --- a/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs +++ b/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs @@ -1,21 +1,21 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityObject = UnityEngine.Object; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class ScriptableData : ScriptableObject - { - [SerializeField] - private T m_Data; - public UnityObject owner { get; set; } - public int index { get; set; } - - public T data - { - get { return m_Data; } - set { m_Data = value; } - } - } -} +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityObject = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class ScriptableData : ScriptableObject + { + [SerializeField] + private T m_Data; + public UnityObject owner { get; set; } + public int index { get; set; } + + public T data + { + get { return m_Data; } + set { m_Data = value; } + } + } +} diff --git a/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs.meta b/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs.meta index bb073fe..1428e90 100644 --- a/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/ScriptableData.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: b44b92018835a70489d26d1111176fab -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b44b92018835a70489d26d1111176fab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs b/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs index 16ac490..6ae7feb 100644 --- a/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs +++ b/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs @@ -1,118 +1,123 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.EditorTools; -using UnityObject = UnityEngine.Object; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class ScriptablePath : ScriptableObject, IEditablePath, IUndoObject - { - [SerializeField] - private EditablePath m_EditablePath = new EditablePath(); - [SerializeField] - private bool m_Modified = false; - - internal bool modified - { - get { return m_Modified; } - } - - internal UnityObject owner { get; set; } - - public ShapeType shapeType - { - get { return m_EditablePath.shapeType; } - set { m_EditablePath.shapeType = value; } - } - - public IUndoObject undoObject - { - get { return this; } - set { } - } - - public ISelection selection - { - get { return m_EditablePath.selection; } - } - - public Matrix4x4 localToWorldMatrix - { - get { return m_EditablePath.localToWorldMatrix; } - set { m_EditablePath.localToWorldMatrix = value; } - } - - public Vector3 forward - { - get { return m_EditablePath.forward; } - set { m_EditablePath.forward = value; } - } - - public Vector3 up - { - get { return m_EditablePath.up; } - set { m_EditablePath.up = value; } - } - - public Vector3 right - { - get { return m_EditablePath.right; } - set { m_EditablePath.right = value; } - } - - public bool isOpenEnded - { - get { return m_EditablePath.isOpenEnded; } - set { m_EditablePath.isOpenEnded = value; } - } - - public int pointCount - { - get { return m_EditablePath.pointCount; } - } - - public bool Select(ISelector selector) - { - return m_EditablePath.Select(selector); - } - - public virtual void Clear() - { - m_EditablePath.Clear(); - } - - public virtual ControlPoint GetPoint(int index) - { - return m_EditablePath.GetPoint(index); - } - - public virtual void SetPoint(int index, ControlPoint controlPoint) - { - m_EditablePath.SetPoint(index, controlPoint); - } - - public virtual void AddPoint(ControlPoint controlPoint) - { - m_EditablePath.AddPoint(controlPoint); - } - - public virtual void InsertPoint(int index, ControlPoint controlPoint) - { - m_EditablePath.InsertPoint(index, controlPoint); - } - - public virtual void RemovePoint(int index) - { - m_EditablePath.RemovePoint(index); - } - - void IUndoObject.RegisterUndo(string name) - { - Undo.RegisterCompleteObjectUndo(this, name); - m_Modified = true; - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.EditorTools; +using UnityObject = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class ScriptablePath : ScriptableObject, IEditablePath, IUndoObject + { + [SerializeField] + private EditablePath m_EditablePath = new EditablePath(); + [SerializeField] + private bool m_Modified = false; + + internal bool modified + { + get { return m_Modified; } + } + + internal UnityObject owner { get; set; } + + public ShapeType shapeType + { + get { return m_EditablePath.shapeType; } + set { m_EditablePath.shapeType = value; } + } + + public IUndoObject undoObject + { + get { return this; } + set { } + } + + public ISelection selection + { + get { return m_EditablePath.selection; } + } + + public Matrix4x4 localToWorldMatrix + { + get { return m_EditablePath.localToWorldMatrix; } + set { m_EditablePath.localToWorldMatrix = value; } + } + + public Vector3 forward + { + get { return m_EditablePath.forward; } + set { m_EditablePath.forward = value; } + } + + public Vector3 up + { + get { return m_EditablePath.up; } + set { m_EditablePath.up = value; } + } + + public Vector3 right + { + get { return m_EditablePath.right; } + set { m_EditablePath.right = value; } + } + + public bool isOpenEnded + { + get { return m_EditablePath.isOpenEnded; } + set { m_EditablePath.isOpenEnded = value; } + } + + public int pointCount + { + get { return m_EditablePath.pointCount; } + } + + public bool Select(ISelector selector) + { + return m_EditablePath.Select(selector); + } + + public virtual void Clear() + { + m_EditablePath.Clear(); + } + + public virtual ControlPoint GetPoint(int index) + { + return m_EditablePath.GetPoint(index); + } + + public virtual void SetPoint(int index, ControlPoint controlPoint) + { + m_EditablePath.SetPoint(index, controlPoint); + } + + public virtual void AddPoint(ControlPoint controlPoint) + { + m_EditablePath.AddPoint(controlPoint); + } + + public virtual void InsertPoint(int index, ControlPoint controlPoint) + { + m_EditablePath.InsertPoint(index, controlPoint); + } + + public virtual void RemovePoint(int index) + { + m_EditablePath.RemovePoint(index); + } + + void IUndoObject.RegisterUndo(string name) + { + Undo.RegisterCompleteObjectUndo(this, name); + m_Modified = true; + } + + public virtual void SetDefaultShape() + { + m_Modified = true; + } + } +} diff --git a/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs.meta b/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs.meta index 50638af..04f8626 100644 --- a/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/ScriptablePath.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 872bd0128a56e0c488c6fe1286247ab4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 872bd0128a56e0c488c6fe1286247ab4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs b/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs index 5686845..c066239 100644 --- a/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs +++ b/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs @@ -1,233 +1,242 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - [CanEditMultipleObjects] - [CustomEditor(typeof(ScriptablePath), true)] - internal class ScriptablePathInspector : Editor - { - private static class Contents - { - public static readonly GUIContent linearIcon = IconContent("TangentLinear", "TangentLinearPro", "Linear"); - public static readonly GUIContent continuousIcon = IconContent("TangentContinuous", "TangentContinuousPro", "Continuous"); - public static readonly GUIContent brokenIcon = IconContent("TangentBroken", "TangentBrokenPro", "Broken"); - public static readonly GUIContent positionLabel = new GUIContent("Position", "Position of the Control Point"); - public static readonly GUIContent enableSnapLabel = new GUIContent("Snapping", "Snap points using the snap settings"); - public static readonly GUIContent tangentModeLabel = new GUIContent("Tangent Mode"); - public static readonly GUIContent pointLabel = new GUIContent("Point"); - - - private static GUIContent IconContent(string name, string tooltip = null) - { - return new GUIContent(Resources.Load(name), tooltip); - } - - private static GUIContent IconContent(string personal, string pro, string tooltip) - { - if (EditorGUIUtility.isProSkin) - return IconContent(pro, tooltip); - - return IconContent(personal, tooltip); - } - } - - private List m_Paths = null; - private bool m_Dragged = false; - - protected List paths - { - get - { - if (m_Paths == null) - m_Paths = targets.Select( t => t as ScriptablePath).ToList(); - - return m_Paths; - } - } - - public override void OnInspectorGUI() - { - DoTangentModeInspector(); - DoPositionInspector(); - } - - protected void DoTangentModeInspector() - { - if (!IsAnyShapeType(ShapeType.Spline)) - return; - - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel(Contents.tangentModeLabel); - - using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected())) - { - if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Linear), Contents.linearIcon)) - SetMixedTangentMode(TangentMode.Linear); - - if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Continuous), Contents.continuousIcon)) - SetMixedTangentMode(TangentMode.Continuous); - - if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Broken), Contents.brokenIcon)) - SetMixedTangentMode(TangentMode.Broken); - } - - EditorGUILayout.EndHorizontal(); - } - - protected void DoPositionInspector() - { - var showMixedValue = EditorGUI.showMixedValue; - var wideMode = EditorGUIUtility.wideMode; - - var position = Vector3.zero; - var isMixed = GetMixedPosition(out position); - - EditorGUI.showMixedValue = isMixed; - EditorGUIUtility.wideMode = true; - - using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected())) - { - if (GUIUtility.hotControl == 0) - m_Dragged = false; - - EditorGUI.BeginChangeCheck(); - - var delta = EditorGUILayout.Vector2Field(Contents.positionLabel, position) - (Vector2)position; - - if (EditorGUI.EndChangeCheck()) - { - if (m_Dragged == false) - { - foreach(var path in paths) - path.undoObject.RegisterUndo("Point Position"); - - m_Dragged = true; - } - - SetMixedDeltaPosition(delta); - } - } - - EditorGUI.showMixedValue = showMixedValue; - EditorGUIUtility.wideMode = wideMode; - } - - private bool DoToggle(bool value, GUIContent icon) - { - const float kButtonWidth = 33f; - const float kButtonHeight = 23f; - var buttonStyle = new GUIStyle("EditModeSingleButton"); - - var changed = false; - using (var check = new EditorGUI.ChangeCheckScope()) - { - value = GUILayout.Toggle(value, icon, buttonStyle, GUILayout.Width(kButtonWidth), GUILayout.Height(kButtonHeight)); - changed = check.changed; - } - - return value && changed; - } - - private bool GetToggleStateFromTangentMode(TangentMode mode) - { - foreach(var path in paths) - { - var selection = path.selection; - - foreach (var index in selection.elements) - if (path.GetPoint(index).tangentMode != mode) - return false; - } - - return true; - } - - private void SetMixedTangentMode(TangentMode tangentMode) - { - foreach(var path in paths) - { - path.undoObject.RegisterUndo("Tangent Mode"); - - foreach (var index in path.selection.elements) - path.SetTangentMode(index, tangentMode); - } - - SceneView.RepaintAll(); - } - - private bool GetMixedPosition(out Vector3 position) - { - var first = true; - position = Vector3.zero; - - foreach(var path in paths) - { - var selection = path.selection; - var matrix = path.localToWorldMatrix; - - path.localToWorldMatrix = Matrix4x4.identity; - - foreach (var index in selection.elements) - { - var controlPoint = path.GetPoint(index); - - if (first) - { - position = controlPoint.position; - first = false; - } - else if (position != controlPoint.position) - { - return true; - } - } - - path.localToWorldMatrix = matrix; - } - - return false; - } - - private void SetMixedDeltaPosition(Vector3 delta) - { - foreach(var path in paths) - { - var selection = path.selection; - var matrix = path.localToWorldMatrix; - - path.localToWorldMatrix = Matrix4x4.identity; - - foreach (var index in selection.elements) - { - var controlPoint = path.GetPoint(index); - controlPoint.position += delta; - path.SetPoint(index, controlPoint); - } - - path.localToWorldMatrix = matrix; - } - } - - private bool IsAnyShapeType(ShapeType shapeType) - { - foreach(var path in paths) - if (path.shapeType == shapeType) - return true; - - return false; - } - - protected bool IsAnyPointSelected() - { - foreach(var path in paths) - if (path.selection.Count > 0) - return true; - - return false; - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(ScriptablePath), true)] + internal class ScriptablePathInspector : Editor + { + private static class Contents + { + public static readonly GUIContent linearIcon = IconContent("TangentLinear", "TangentLinearPro", "Linear"); + public static readonly GUIContent continuousIcon = IconContent("TangentContinuous", "TangentContinuousPro", "Continuous"); + public static readonly GUIContent brokenIcon = IconContent("TangentBroken", "TangentBrokenPro", "Broken"); + public static readonly GUIContent positionLabel = new GUIContent("Position", "Position of the Control Point"); + public static readonly GUIContent enableSnapLabel = new GUIContent("Snapping", "Snap points using the snap settings"); + public static readonly GUIContent tangentModeLabel = new GUIContent("Tangent Mode"); + public static readonly GUIContent pointLabel = new GUIContent("Point"); + + + private static GUIContent IconContent(string name, string tooltip = null) + { + return new GUIContent(Resources.Load(name), tooltip); + } + + private static GUIContent IconContent(string personal, string pro, string tooltip) + { + if (EditorGUIUtility.isProSkin) + return IconContent(pro, tooltip); + + return IconContent(personal, tooltip); + } + } + + private List m_Paths = null; + private bool m_Dragged = false; + + protected List paths + { + get + { + if (m_Paths == null) + m_Paths = targets.Select(t => t as ScriptablePath).ToList(); + + return m_Paths; + } + } + + public override void OnInspectorGUI() + { + DoTangentModeInspector(); + DoPositionInspector(); + } + + protected void DoTangentModeInspector() + { + if (!IsAnyShapeType(ShapeType.Spline)) + return; + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel(Contents.tangentModeLabel); + + using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected())) + { + if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Linear), Contents.linearIcon)) + SetMixedTangentMode(TangentMode.Linear); + + if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Continuous), Contents.continuousIcon)) + SetMixedTangentMode(TangentMode.Continuous); + + if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Broken), Contents.brokenIcon)) + SetMixedTangentMode(TangentMode.Broken); + } + + EditorGUILayout.EndHorizontal(); + } + + protected void DoPositionInspector() + { + var showMixedValue = EditorGUI.showMixedValue; + var wideMode = EditorGUIUtility.wideMode; + + var position = Vector3.zero; + var isMixed = GetMixedPosition(out position); + + EditorGUI.showMixedValue = isMixed; + EditorGUIUtility.wideMode = true; + + using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected())) + { + if (GUIUtility.hotControl == 0) + m_Dragged = false; + + EditorGUI.BeginChangeCheck(); + + var delta = EditorGUILayout.Vector2Field(Contents.positionLabel, position) - (Vector2)position; + + if (EditorGUI.EndChangeCheck()) + { + if (m_Dragged == false) + { + foreach (var path in paths) + path.undoObject.RegisterUndo("Point Position"); + + m_Dragged = true; + } + + SetMixedDeltaPosition(delta); + } + } + + EditorGUI.showMixedValue = showMixedValue; + EditorGUIUtility.wideMode = wideMode; + } + + private bool DoToggle(bool value, GUIContent icon) + { + const float kButtonWidth = 33f; + const float kButtonHeight = 23f; + var buttonStyle = new GUIStyle("EditModeSingleButton"); + + var changed = false; + using (var check = new EditorGUI.ChangeCheckScope()) + { + value = GUILayout.Toggle(value, icon, buttonStyle, GUILayout.Width(kButtonWidth), GUILayout.Height(kButtonHeight)); + changed = check.changed; + } + + return value && changed; + } + + private bool GetToggleStateFromTangentMode(TangentMode mode) + { + foreach (var path in paths) + { + var selection = path.selection; + + foreach (var index in selection.elements) + if (path.GetPoint(index).tangentMode != mode) + return false; + } + + return true; + } + + private void SetMixedTangentMode(TangentMode tangentMode) + { + foreach (var path in paths) + { + path.undoObject.RegisterUndo("Tangent Mode"); + + foreach (var index in path.selection.elements) + path.SetTangentMode(index, tangentMode); + } + + SceneView.RepaintAll(); + } + + private bool GetMixedPosition(out Vector3 position) + { + var first = true; + position = Vector3.zero; + var activeObject = Selection.activeObject as GameObject; + + if (Selection.count > 1 || !activeObject) + return true; + var lightObject = activeObject.GetComponent(); + var shadowCaster = activeObject.GetComponent(); + + foreach (var path in paths) + { + var selection = path.selection; + var matrix = path.localToWorldMatrix; + if (lightObject == path.owner || shadowCaster == path.owner) + { + path.localToWorldMatrix = Matrix4x4.identity; + + foreach (var index in selection.elements) + { + var controlPoint = path.GetPoint(index); + + if (first) + { + position = controlPoint.position; + first = false; + } + else if (position != controlPoint.position) + { + return true; + } + } + } + + path.localToWorldMatrix = matrix; + } + + return false; + } + + private void SetMixedDeltaPosition(Vector3 delta) + { + foreach (var path in paths) + { + var selection = path.selection; + var matrix = path.localToWorldMatrix; + + path.localToWorldMatrix = Matrix4x4.identity; + + foreach (var index in selection.elements) + { + var controlPoint = path.GetPoint(index); + controlPoint.position += delta; + path.SetPoint(index, controlPoint); + } + + path.localToWorldMatrix = matrix; + } + } + + private bool IsAnyShapeType(ShapeType shapeType) + { + foreach (var path in paths) + if (path.shapeType == shapeType) + return true; + + return false; + } + + protected bool IsAnyPointSelected() + { + foreach (var path in paths) + if (path.selection.Count > 0) + return true; + + return false; + } + } +} diff --git a/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs.meta b/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs.meta index 96086a8..0fbf696 100644 --- a/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs.meta +++ b/Editor/2D/ShapeEditor/EditorTool/ScriptablePathInspector.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: dea208c009cd4d04abcb44383a67b755 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: dea208c009cd4d04abcb44383a67b755 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework.meta b/Editor/2D/ShapeEditor/GUIFramework.meta index a439b21..7f93fbe 100644 --- a/Editor/2D/ShapeEditor/GUIFramework.meta +++ b/Editor/2D/ShapeEditor/GUIFramework.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: a7c7330a528534e4a947801ac7b09144 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: a7c7330a528534e4a947801ac7b09144 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs b/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs index 0ae5615..e40be14 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs @@ -1,40 +1,40 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class ClickAction : HoveredControlAction - { - private int m_Button; - private bool m_UseEvent; - - public Action onClick; - - public ClickAction(Control control, int button, bool useEvent = true) : base(control) - { - m_Button = button; - m_UseEvent = useEvent; - } - - protected override bool GetTriggerContidtion(IGUIState guiState) - { - return guiState.mouseButton == m_Button && guiState.eventType == EventType.MouseDown; - } - - protected override void OnTrigger(IGUIState guiState) - { - base.OnTrigger(guiState); - - if (onClick != null) - onClick(guiState, hoveredControl); - - if (m_UseEvent) - guiState.UseCurrentEvent(); - } - - protected override bool GetFinishContidtion(IGUIState guiState) - { - return true; - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class ClickAction : HoveredControlAction + { + private int m_Button; + private bool m_UseEvent; + + public Action onClick; + + public ClickAction(Control control, int button, bool useEvent = true) : base(control) + { + m_Button = button; + m_UseEvent = useEvent; + } + + protected override bool GetTriggerContidtion(IGUIState guiState) + { + return guiState.mouseButton == m_Button && guiState.eventType == EventType.MouseDown; + } + + protected override void OnTrigger(IGUIState guiState) + { + base.OnTrigger(guiState); + + if (onClick != null) + onClick(guiState, hoveredControl); + + if (m_UseEvent) + guiState.UseCurrentEvent(); + } + + protected override bool GetFinishContidtion(IGUIState guiState) + { + return true; + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs.meta index 651c847..d616a52 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/ClickAction.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 6af2f835ebda04142bb7bf91ef10fe9c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 6af2f835ebda04142bb7bf91ef10fe9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs b/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs index 90ae13b..0753712 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs @@ -1,46 +1,46 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class CommandAction : GUIAction - { - private string m_CommandName; - - public Action onCommand; - - public CommandAction(string commandName) - { - m_CommandName = commandName; - } - - protected override bool GetTriggerContidtion(IGUIState guiState) - { - if (guiState.eventType == EventType.ValidateCommand && guiState.commandName == m_CommandName) - { - guiState.UseCurrentEvent(); - return true; - } - - return false; - } - - protected override bool GetFinishContidtion(IGUIState guiState) - { - if (guiState.eventType == EventType.ExecuteCommand && guiState.commandName == m_CommandName) - { - guiState.UseCurrentEvent(); - - return true; - } - - return false; - } - - protected override void OnFinish(IGUIState guiState) - { - if (onCommand != null) - onCommand(guiState); - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class CommandAction : GUIAction + { + private string m_CommandName; + + public Action onCommand; + + public CommandAction(string commandName) + { + m_CommandName = commandName; + } + + protected override bool GetTriggerContidtion(IGUIState guiState) + { + if (guiState.eventType == EventType.ValidateCommand && guiState.commandName == m_CommandName) + { + guiState.UseCurrentEvent(); + return true; + } + + return false; + } + + protected override bool GetFinishContidtion(IGUIState guiState) + { + if (guiState.eventType == EventType.ExecuteCommand && guiState.commandName == m_CommandName) + { + guiState.UseCurrentEvent(); + + return true; + } + + return false; + } + + protected override void OnFinish(IGUIState guiState) + { + if (onCommand != null) + onCommand(guiState); + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs.meta index a12de99..23950bc 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/CommandAction.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 51ffc0643368a6f4a98bcccc751da206 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 51ffc0643368a6f4a98bcccc751da206 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/Control.cs b/Editor/2D/ShapeEditor/GUIFramework/Control.cs index d8cd79e..4a31bd2 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/Control.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/Control.cs @@ -1,152 +1,150 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal abstract class Control - { - private string m_Name; - private int m_NameHashCode; - private int m_ID; - private LayoutData m_LayoutData; - private int m_ActionID = -1; - private LayoutData m_HotLayoutData; - - public string name - { - get { return m_Name; } - } - - public int ID - { - get { return m_ID; } - } - - public int actionID - { - get { return m_ActionID; } - } - - public LayoutData layoutData - { - get { return m_LayoutData; } - set { m_LayoutData = value; } - } - - public LayoutData hotLayoutData - { - get { return m_HotLayoutData; } - } - - public Control(string name) - { - m_Name = name; - m_NameHashCode = name.GetHashCode(); - } - - public void GetControl(IGUIState guiState) - { - m_ID = guiState.GetControlID(m_NameHashCode, FocusType.Passive); - } - - internal void SetActionID(int actionID) - { - m_ActionID = actionID; - m_HotLayoutData = m_LayoutData; - } - - public void BeginLayout(IGUIState guiState) - { - Debug.Assert(guiState.eventType == EventType.Layout); - - m_LayoutData = OnBeginLayout(LayoutData.zero, guiState); - } - - public void Layout(IGUIState guiState) - { - Debug.Assert(guiState.eventType == EventType.Layout); - - for (var i = 0; i < GetCount(); ++i) - { - if (guiState.hotControl == actionID && hotLayoutData.index == i) - continue; - - var layoutData = new LayoutData() - { - index = i, - position = GetPosition(guiState, i), - distance = GetDistance(guiState, i), - forward = GetForward(guiState, i), - up = GetUp(guiState, i), - right = GetRight(guiState, i), - userData = GetUserData(guiState, i) - }; - - m_LayoutData = LayoutData.Nearest(m_LayoutData, layoutData); - } - } - - public void EndLayout(IGUIState guiState) - { - Debug.Assert(guiState.eventType == EventType.Layout); - - OnEndLayout(guiState); - } - - public void Repaint(IGUIState guiState) - { - for (var i = 0; i < GetCount(); ++i) - OnRepaint(guiState, i); - } - - protected virtual LayoutData OnBeginLayout(LayoutData data, IGUIState guiState) - { - return data; - } - - protected virtual void OnEndLayout(IGUIState guiState) - { - - } - - protected virtual void OnRepaint(IGUIState guiState, int index) - { - - } - - protected virtual int GetCount() - { - return 1; - } - - protected virtual Vector3 GetPosition(IGUIState guiState, int index) - { - return Vector3.zero; - } - - protected virtual Vector3 GetForward(IGUIState guiState, int index) - { - return Vector3.forward; - } - - protected virtual Vector3 GetUp(IGUIState guiState, int index) - { - return Vector3.up; - } - - protected virtual Vector3 GetRight(IGUIState guiState, int index) - { - return Vector3.right; - } - - protected virtual float GetDistance(IGUIState guiState, int index) - { - return layoutData.distance; - } - - protected virtual object GetUserData(IGUIState guiState, int index) - { - return null; - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal abstract class Control + { + private string m_Name; + private int m_NameHashCode; + private int m_ID; + private LayoutData m_LayoutData; + private int m_ActionID = -1; + private LayoutData m_HotLayoutData; + + public string name + { + get { return m_Name; } + } + + public int ID + { + get { return m_ID; } + } + + public int actionID + { + get { return m_ActionID; } + } + + public LayoutData layoutData + { + get { return m_LayoutData; } + set { m_LayoutData = value; } + } + + public LayoutData hotLayoutData + { + get { return m_HotLayoutData; } + } + + public Control(string name) + { + m_Name = name; + m_NameHashCode = name.GetHashCode(); + } + + public void GetControl(IGUIState guiState) + { + m_ID = guiState.GetControlID(m_NameHashCode, FocusType.Passive); + } + + internal void SetActionID(int actionID) + { + m_ActionID = actionID; + m_HotLayoutData = m_LayoutData; + } + + public void BeginLayout(IGUIState guiState) + { + Debug.Assert(guiState.eventType == EventType.Layout); + + m_LayoutData = OnBeginLayout(LayoutData.zero, guiState); + } + + public void Layout(IGUIState guiState) + { + Debug.Assert(guiState.eventType == EventType.Layout); + + for (var i = 0; i < GetCount(); ++i) + { + if (guiState.hotControl == actionID && hotLayoutData.index == i) + continue; + + var layoutData = new LayoutData() + { + index = i, + position = GetPosition(guiState, i), + distance = GetDistance(guiState, i), + forward = GetForward(guiState, i), + up = GetUp(guiState, i), + right = GetRight(guiState, i), + userData = GetUserData(guiState, i) + }; + + m_LayoutData = LayoutData.Nearest(m_LayoutData, layoutData); + } + } + + public void EndLayout(IGUIState guiState) + { + Debug.Assert(guiState.eventType == EventType.Layout); + + OnEndLayout(guiState); + } + + public void Repaint(IGUIState guiState) + { + for (var i = 0; i < GetCount(); ++i) + OnRepaint(guiState, i); + } + + protected virtual LayoutData OnBeginLayout(LayoutData data, IGUIState guiState) + { + return data; + } + + protected virtual void OnEndLayout(IGUIState guiState) + { + } + + protected virtual void OnRepaint(IGUIState guiState, int index) + { + } + + protected virtual int GetCount() + { + return 1; + } + + protected virtual Vector3 GetPosition(IGUIState guiState, int index) + { + return Vector3.zero; + } + + protected virtual Vector3 GetForward(IGUIState guiState, int index) + { + return Vector3.forward; + } + + protected virtual Vector3 GetUp(IGUIState guiState, int index) + { + return Vector3.up; + } + + protected virtual Vector3 GetRight(IGUIState guiState, int index) + { + return Vector3.right; + } + + protected virtual float GetDistance(IGUIState guiState, int index) + { + return layoutData.distance; + } + + protected virtual object GetUserData(IGUIState guiState, int index) + { + return null; + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/Control.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/Control.cs.meta index 9fd8af6..b929423 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/Control.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/Control.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 2f8a81fd38944184faca74bce64a9759 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 2f8a81fd38944184faca74bce64a9759 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs b/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs index 653f266..8e73a11 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs @@ -1,20 +1,20 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal abstract class DefaultControl : Control - { - public static readonly float kPickDistance = 5f; - - public DefaultControl(string name) : base(name) - { - } - - protected override LayoutData OnBeginLayout(LayoutData data, IGUIState guiState) - { - data.distance = kPickDistance; - return data; - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal abstract class DefaultControl : Control + { + public static readonly float kPickDistance = 5f; + + public DefaultControl(string name) : base(name) + { + } + + protected override LayoutData OnBeginLayout(LayoutData data, IGUIState guiState) + { + data.distance = kPickDistance; + return data; + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs.meta index e96d7fe..3443ccc 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/DefaultControl.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: ee2b57f7c56382f4bab83d6cefbfa683 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ee2b57f7c56382f4bab83d6cefbfa683 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs b/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs index 340c74b..619e063 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs @@ -1,112 +1,109 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal abstract class GUIAction - { - private int m_ID = -1; - - public Func enable; - public Func enableRepaint; - public Func repaintOnMouseMove; - public Action onPreRepaint; - public Action onRepaint; - - public int ID - { - get { return m_ID; } - } - - public void OnGUI(IGUIState guiState) - { - m_ID = guiState.GetControlID(GetType().GetHashCode(), FocusType.Passive); - - if (guiState.hotControl == 0 && IsEnabled(guiState) && CanTrigger(guiState) && GetTriggerContidtion(guiState)) - { - guiState.hotControl = ID; - OnTrigger(guiState); - } - - if (guiState.hotControl == ID) - { - if (GetFinishContidtion(guiState)) - { - OnFinish(guiState); - guiState.hotControl = 0; - } - else - { - OnPerform(guiState); - } - } - - if (guiState.eventType == EventType.Repaint && IsRepaintEnabled(guiState)) - Repaint(guiState); - } - - public bool IsEnabled(IGUIState guiState) - { - if (enable != null) - return enable(guiState, this); - - return true; - } - - public bool IsRepaintEnabled(IGUIState guiState) - { - if (!IsEnabled(guiState)) - return false; - - if (enableRepaint != null) - return enableRepaint(guiState, this); - - return true; - } - - public void PreRepaint(IGUIState guiState) - { - Debug.Assert(guiState.eventType == EventType.Repaint); - - if (IsEnabled(guiState) && onPreRepaint != null) - onPreRepaint(guiState, this); - } - - private void Repaint(IGUIState guiState) - { - Debug.Assert(guiState.eventType == EventType.Repaint); - - if (onRepaint != null) - onRepaint(guiState, this); - } - - internal bool IsRepaintOnMouseMoveEnabled(IGUIState guiState) - { - if (!IsEnabled(guiState) || !IsRepaintEnabled(guiState)) - return false; - - if (repaintOnMouseMove != null) - return repaintOnMouseMove(guiState, this); - - return false; - } - - protected abstract bool GetFinishContidtion(IGUIState guiState); - protected abstract bool GetTriggerContidtion(IGUIState guiState); - protected virtual bool CanTrigger(IGUIState guiState) { return true; } - protected virtual void OnTrigger(IGUIState guiState) - { - - } - - protected virtual void OnPerform(IGUIState guiState) - { - - } - - protected virtual void OnFinish(IGUIState guiState) - { - - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal abstract class GUIAction + { + private int m_ID = -1; + + public Func enable; + public Func enableRepaint; + public Func repaintOnMouseMove; + public Action onPreRepaint; + public Action onRepaint; + + public int ID + { + get { return m_ID; } + } + + public void OnGUI(IGUIState guiState) + { + m_ID = guiState.GetControlID(GetType().GetHashCode(), FocusType.Passive); + + if (guiState.hotControl == 0 && IsEnabled(guiState) && CanTrigger(guiState) && GetTriggerContidtion(guiState)) + { + guiState.hotControl = ID; + OnTrigger(guiState); + } + + if (guiState.hotControl == ID) + { + if (GetFinishContidtion(guiState)) + { + OnFinish(guiState); + guiState.hotControl = 0; + } + else + { + OnPerform(guiState); + } + } + + if (guiState.eventType == EventType.Repaint && IsRepaintEnabled(guiState)) + Repaint(guiState); + } + + public bool IsEnabled(IGUIState guiState) + { + if (enable != null) + return enable(guiState, this); + + return true; + } + + public bool IsRepaintEnabled(IGUIState guiState) + { + if (!IsEnabled(guiState)) + return false; + + if (enableRepaint != null) + return enableRepaint(guiState, this); + + return true; + } + + public void PreRepaint(IGUIState guiState) + { + Debug.Assert(guiState.eventType == EventType.Repaint); + + if (IsEnabled(guiState) && onPreRepaint != null) + onPreRepaint(guiState, this); + } + + private void Repaint(IGUIState guiState) + { + Debug.Assert(guiState.eventType == EventType.Repaint); + + if (onRepaint != null) + onRepaint(guiState, this); + } + + internal bool IsRepaintOnMouseMoveEnabled(IGUIState guiState) + { + if (!IsEnabled(guiState) || !IsRepaintEnabled(guiState)) + return false; + + if (repaintOnMouseMove != null) + return repaintOnMouseMove(guiState, this); + + return false; + } + + protected abstract bool GetFinishContidtion(IGUIState guiState); + protected abstract bool GetTriggerContidtion(IGUIState guiState); + protected virtual bool CanTrigger(IGUIState guiState) { return true; } + protected virtual void OnTrigger(IGUIState guiState) + { + } + + protected virtual void OnPerform(IGUIState guiState) + { + } + + protected virtual void OnFinish(IGUIState guiState) + { + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs.meta index 69b2044..b24d206 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/GUIAction.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 9c57b0c9f1098ea44831508487f7694b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 9c57b0c9f1098ea44831508487f7694b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs b/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs index 4ba0ddc..8a21ba6 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs @@ -1,165 +1,165 @@ -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class GUIState : IGUIState - { - private Handles.CapFunction nullCap = (int c, Vector3 p , Quaternion r, float s, EventType ev) => {}; - - public Vector2 mousePosition - { - get { return Event.current.mousePosition; } - } - - public int mouseButton - { - get { return Event.current.button; } - } - - public int clickCount - { - get { return Event.current.clickCount; } - } - - public bool isShiftDown - { - get { return Event.current.shift; } - } - - public bool isAltDown - { - get { return Event.current.alt; } - } - - public bool isActionKeyDown - { - get { return EditorGUI.actionKey; } - } - - public KeyCode keyCode - { - get { return Event.current.keyCode; } - } - - public EventType eventType - { - get { return Event.current.type; } - } - - public string commandName - { - get { return Event.current.commandName; } - } - - public int nearestControl - { - get { return HandleUtility.nearestControl; } - set { HandleUtility.nearestControl = value; } - } - - public int hotControl - { - get { return GUIUtility.hotControl; } - set { GUIUtility.hotControl = value; } - } - - public bool changed - { - get { return GUI.changed; } - set { GUI.changed = value; } - } - - public int GetControlID(int hint, FocusType focusType) - { - return GUIUtility.GetControlID(hint, focusType); - } - - public void AddControl(int controlID, float distance) - { - HandleUtility.AddControl(controlID, distance); - } - - public bool Slider(int id, SliderData sliderData, out Vector3 newPosition) - { - if (mouseButton == 0 && eventType == EventType.MouseDown) - { - hotControl = 0; - nearestControl = id; - } - - EditorGUI.BeginChangeCheck(); - newPosition = Handles.Slider2D(id, sliderData.position, sliderData.forward, sliderData.right, sliderData.up, 1f, nullCap, Vector2.zero); - return EditorGUI.EndChangeCheck(); - } - - public void UseCurrentEvent() - { - Event.current.Use(); - } - - public void Repaint() - { - HandleUtility.Repaint(); - } - - public bool IsEventOutsideWindow() - { - return Event.current.type == EventType.Ignore; - } - - public bool IsViewToolActive() - { - return UnityEditor.Tools.current == Tool.View || isAltDown || mouseButton == 1 || mouseButton == 2; - } - - public bool HasCurrentCamera() - { - return Camera.current != null; - } - - public float GetHandleSize(Vector3 position) - { - var scale = HasCurrentCamera() ? 0.01f : 0.05f; - return HandleUtility.GetHandleSize(position) * scale; - } - - public float DistanceToSegment(Vector3 p1, Vector3 p2) - { - p1 = HandleUtility.WorldToGUIPoint(p1); - p2 = HandleUtility.WorldToGUIPoint(p2); - - return HandleUtility.DistancePointToLineSegment(Event.current.mousePosition, p1, p2); - } - - public float DistanceToCircle(Vector3 center, float radius) - { - return HandleUtility.DistanceToCircle(center, radius); - } - - public Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos) - { - Vector3 worldPos = Handles.inverseMatrix.MultiplyPoint(guiPosition); - - if (Camera.current) - { - Ray ray = HandleUtility.GUIPointToWorldRay(guiPosition); - - planeNormal = Handles.matrix.MultiplyVector(planeNormal); - - planePos = Handles.matrix.MultiplyPoint(planePos); - - Plane plane = new Plane(planeNormal, planePos); - - float distance = 0f; - - if (plane.Raycast(ray, out distance)) - { - worldPos = Handles.inverseMatrix.MultiplyPoint(ray.GetPoint(distance)); - } - } - - return worldPos; - } - } -} +using UnityEngine; +using UnityEditor; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class GUIState : IGUIState + { + private Handles.CapFunction nullCap = (int c, Vector3 p, Quaternion r, float s, EventType ev) => { }; + + public Vector2 mousePosition + { + get { return Event.current.mousePosition; } + } + + public int mouseButton + { + get { return Event.current.button; } + } + + public int clickCount + { + get { return Event.current.clickCount; } + } + + public bool isShiftDown + { + get { return Event.current.shift; } + } + + public bool isAltDown + { + get { return Event.current.alt; } + } + + public bool isActionKeyDown + { + get { return EditorGUI.actionKey; } + } + + public KeyCode keyCode + { + get { return Event.current.keyCode; } + } + + public EventType eventType + { + get { return Event.current.type; } + } + + public string commandName + { + get { return Event.current.commandName; } + } + + public int nearestControl + { + get { return HandleUtility.nearestControl; } + set { HandleUtility.nearestControl = value; } + } + + public int hotControl + { + get { return GUIUtility.hotControl; } + set { GUIUtility.hotControl = value; } + } + + public bool changed + { + get { return GUI.changed; } + set { GUI.changed = value; } + } + + public int GetControlID(int hint, FocusType focusType) + { + return GUIUtility.GetControlID(hint, focusType); + } + + public void AddControl(int controlID, float distance) + { + HandleUtility.AddControl(controlID, distance); + } + + public bool Slider(int id, SliderData sliderData, out Vector3 newPosition) + { + if (mouseButton == 0 && eventType == EventType.MouseDown) + { + hotControl = 0; + nearestControl = id; + } + + EditorGUI.BeginChangeCheck(); + newPosition = Handles.Slider2D(id, sliderData.position, sliderData.forward, sliderData.right, sliderData.up, 1f, nullCap, Vector2.zero); + return EditorGUI.EndChangeCheck(); + } + + public void UseCurrentEvent() + { + Event.current.Use(); + } + + public void Repaint() + { + HandleUtility.Repaint(); + } + + public bool IsEventOutsideWindow() + { + return Event.current.type == EventType.Ignore; + } + + public bool IsViewToolActive() + { + return UnityEditor.Tools.current == Tool.View || isAltDown || mouseButton == 1 || mouseButton == 2; + } + + public bool HasCurrentCamera() + { + return Camera.current != null; + } + + public float GetHandleSize(Vector3 position) + { + var scale = HasCurrentCamera() ? 0.01f : 0.05f; + return HandleUtility.GetHandleSize(position) * scale; + } + + public float DistanceToSegment(Vector3 p1, Vector3 p2) + { + p1 = HandleUtility.WorldToGUIPoint(p1); + p2 = HandleUtility.WorldToGUIPoint(p2); + + return HandleUtility.DistancePointToLineSegment(Event.current.mousePosition, p1, p2); + } + + public float DistanceToCircle(Vector3 center, float radius) + { + return HandleUtility.DistanceToCircle(center, radius); + } + + public Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos) + { + Vector3 worldPos = Handles.inverseMatrix.MultiplyPoint(guiPosition); + + if (Camera.current) + { + Ray ray = HandleUtility.GUIPointToWorldRay(guiPosition); + + planeNormal = Handles.matrix.MultiplyVector(planeNormal); + + planePos = Handles.matrix.MultiplyPoint(planePos); + + Plane plane = new Plane(planeNormal, planePos); + + float distance = 0f; + + if (plane.Raycast(ray, out distance)) + { + worldPos = Handles.inverseMatrix.MultiplyPoint(ray.GetPoint(distance)); + } + } + + return worldPos; + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs.meta index 05ef9f4..35867f5 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/GUIState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: dfe5c2dc56aadd84082c2f1ffcdd7167 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: dfe5c2dc56aadd84082c2f1ffcdd7167 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs b/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs index a462421..15ba172 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs @@ -1,124 +1,124 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class GUISystem - { - private readonly int kControlIDCheckHashCode = "ControlIDCheckHashCode".GetHashCode(); - - private List m_Controls = new List(); - private List m_Actions = new List(); - private IGUIState m_GUIState; - private int m_PrevNearestControl = -1; - private LayoutData m_PrevNearestLayoutData = LayoutData.zero; - private int m_ControlIDCheck = -1; - - public GUISystem(IGUIState guiState) - { - m_GUIState = guiState; - } - - public void AddControl(Control control) - { - if (control == null) - throw new NullReferenceException("Control is null"); - - m_Controls.Add(control); - } - - public void RemoveControl(Control control) - { - m_Controls.Remove(control); - } - - public void AddAction(GUIAction action) - { - if (action == null) - throw new NullReferenceException("Action is null"); - - m_Actions.Add(action); - } - - public void RemoveAction(GUIAction action) - { - m_Actions.Remove(action); - } - - public void OnGUI() - { - var controlIDCheck = m_GUIState.GetControlID(kControlIDCheckHashCode, FocusType.Passive); - - if (m_GUIState.eventType == EventType.Layout) - m_ControlIDCheck = controlIDCheck; - else if (m_GUIState.eventType != EventType.Used && m_ControlIDCheck != controlIDCheck) - Debug.LogWarning("GetControlID at event " + m_GUIState.eventType + " returns a controlID different from the one in Layout event"); - - var nearestLayoutData = LayoutData.zero; - - foreach (var control in m_Controls) - control.GetControl(m_GUIState); - - if (m_GUIState.eventType == EventType.Layout) - { - foreach (var control in m_Controls) - control.BeginLayout(m_GUIState); - - foreach (var control in m_Controls) - { - control.Layout(m_GUIState); - nearestLayoutData = LayoutData.Nearest(nearestLayoutData, control.layoutData); - } - - foreach (var control in m_Controls) - m_GUIState.AddControl(control.ID, control.layoutData.distance); - - foreach (var control in m_Controls) - control.EndLayout(m_GUIState); - - if (m_PrevNearestControl == m_GUIState.nearestControl) - { - if (nearestLayoutData.index != m_PrevNearestLayoutData.index) - m_GUIState.Repaint(); - } - else - { - m_PrevNearestControl = m_GUIState.nearestControl; - m_GUIState.Repaint(); - } - - m_PrevNearestLayoutData = nearestLayoutData; - } - - if (m_GUIState.eventType == EventType.Repaint) - { - foreach (var action in m_Actions) - if (action.IsRepaintEnabled(m_GUIState)) - action.PreRepaint(m_GUIState); - - foreach (var control in m_Controls) - control.Repaint(m_GUIState); - } - - var repaintOnMouseMove = false; - - foreach (var action in m_Actions) - { - if (IsMouseMoveEvent()) - repaintOnMouseMove |= action.IsRepaintOnMouseMoveEnabled(m_GUIState); - - action.OnGUI(m_GUIState); - } - - if (repaintOnMouseMove) - m_GUIState.UseCurrentEvent(); - } - - private bool IsMouseMoveEvent() - { - return m_GUIState.eventType == EventType.MouseMove || m_GUIState.eventType == EventType.MouseDrag; - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class GUISystem + { + private readonly int kControlIDCheckHashCode = "ControlIDCheckHashCode".GetHashCode(); + + private List m_Controls = new List(); + private List m_Actions = new List(); + private IGUIState m_GUIState; + private int m_PrevNearestControl = -1; + private LayoutData m_PrevNearestLayoutData = LayoutData.zero; + private int m_ControlIDCheck = -1; + + public GUISystem(IGUIState guiState) + { + m_GUIState = guiState; + } + + public void AddControl(Control control) + { + if (control == null) + throw new NullReferenceException("Control is null"); + + m_Controls.Add(control); + } + + public void RemoveControl(Control control) + { + m_Controls.Remove(control); + } + + public void AddAction(GUIAction action) + { + if (action == null) + throw new NullReferenceException("Action is null"); + + m_Actions.Add(action); + } + + public void RemoveAction(GUIAction action) + { + m_Actions.Remove(action); + } + + public void OnGUI() + { + var controlIDCheck = m_GUIState.GetControlID(kControlIDCheckHashCode, FocusType.Passive); + + if (m_GUIState.eventType == EventType.Layout) + m_ControlIDCheck = controlIDCheck; + else if (m_GUIState.eventType != EventType.Used && m_ControlIDCheck != controlIDCheck) + Debug.LogWarning("GetControlID at event " + m_GUIState.eventType + " returns a controlID different from the one in Layout event"); + + var nearestLayoutData = LayoutData.zero; + + foreach (var control in m_Controls) + control.GetControl(m_GUIState); + + if (m_GUIState.eventType == EventType.Layout) + { + foreach (var control in m_Controls) + control.BeginLayout(m_GUIState); + + foreach (var control in m_Controls) + { + control.Layout(m_GUIState); + nearestLayoutData = LayoutData.Nearest(nearestLayoutData, control.layoutData); + } + + foreach (var control in m_Controls) + m_GUIState.AddControl(control.ID, control.layoutData.distance); + + foreach (var control in m_Controls) + control.EndLayout(m_GUIState); + + if (m_PrevNearestControl == m_GUIState.nearestControl) + { + if (nearestLayoutData.index != m_PrevNearestLayoutData.index) + m_GUIState.Repaint(); + } + else + { + m_PrevNearestControl = m_GUIState.nearestControl; + m_GUIState.Repaint(); + } + + m_PrevNearestLayoutData = nearestLayoutData; + } + + if (m_GUIState.eventType == EventType.Repaint) + { + foreach (var action in m_Actions) + if (action.IsRepaintEnabled(m_GUIState)) + action.PreRepaint(m_GUIState); + + foreach (var control in m_Controls) + control.Repaint(m_GUIState); + } + + var repaintOnMouseMove = false; + + foreach (var action in m_Actions) + { + if (IsMouseMoveEvent()) + repaintOnMouseMove |= action.IsRepaintOnMouseMoveEnabled(m_GUIState); + + action.OnGUI(m_GUIState); + } + + if (repaintOnMouseMove) + m_GUIState.UseCurrentEvent(); + } + + private bool IsMouseMoveEvent() + { + return m_GUIState.eventType == EventType.MouseMove || m_GUIState.eventType == EventType.MouseDrag; + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs.meta index d330a09..496dda6 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/GUISystem.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: bc3d95ebb83fadc4696c76170c20fce2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: bc3d95ebb83fadc4696c76170c20fce2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs b/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs index 78db77b..37173cb 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs @@ -1,99 +1,99 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class GenericControl : Control - { - public Func onBeginLayout = null; - public Action onEndLayout = null; - public Action onRepaint; - public Func count; - public Func position; - public Func distance; - public Func forward; - public Func up; - public Func right; - public Func userData = null; - - public GenericControl(string name) : base(name) - { - } - - protected override int GetCount() - { - if (count != null) - return count(); - - return base.GetCount(); - } - - protected override void OnEndLayout(IGUIState guiState) - { - if (onEndLayout != null) - onEndLayout(guiState); - } - - protected override void OnRepaint(IGUIState guiState, int index) - { - if (onRepaint != null) - onRepaint(guiState, this, index); - } - - protected override LayoutData OnBeginLayout(LayoutData data, IGUIState guiState) - { - if (onBeginLayout != null) - return onBeginLayout(guiState); - - return data; - } - - protected override Vector3 GetPosition(IGUIState guiState, int index) - { - if (position != null) - return position(index); - - return base.GetPosition(guiState,index); - } - - protected override float GetDistance(IGUIState guiState, int index) - { - if (distance != null) - return distance(guiState, index); - - return base.GetDistance(guiState, index); - } - - protected override Vector3 GetForward(IGUIState guiState, int index) - { - if (forward != null) - return forward(index); - - return base.GetForward(guiState,index); - } - - protected override Vector3 GetUp(IGUIState guiState, int index) - { - if (up != null) - return up(index); - - return base.GetUp(guiState,index); - } - - protected override Vector3 GetRight(IGUIState guiState, int index) - { - if (right != null) - return right(index); - - return base.GetRight(guiState,index); - } - - protected override object GetUserData(IGUIState guiState, int index) - { - if (userData != null) - return userData(index); - - return base.GetUserData(guiState,index); - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class GenericControl : Control + { + public Func onBeginLayout = null; + public Action onEndLayout = null; + public Action onRepaint; + public Func count; + public Func position; + public Func distance; + public Func forward; + public Func up; + public Func right; + public Func userData = null; + + public GenericControl(string name) : base(name) + { + } + + protected override int GetCount() + { + if (count != null) + return count(); + + return base.GetCount(); + } + + protected override void OnEndLayout(IGUIState guiState) + { + if (onEndLayout != null) + onEndLayout(guiState); + } + + protected override void OnRepaint(IGUIState guiState, int index) + { + if (onRepaint != null) + onRepaint(guiState, this, index); + } + + protected override LayoutData OnBeginLayout(LayoutData data, IGUIState guiState) + { + if (onBeginLayout != null) + return onBeginLayout(guiState); + + return data; + } + + protected override Vector3 GetPosition(IGUIState guiState, int index) + { + if (position != null) + return position(index); + + return base.GetPosition(guiState, index); + } + + protected override float GetDistance(IGUIState guiState, int index) + { + if (distance != null) + return distance(guiState, index); + + return base.GetDistance(guiState, index); + } + + protected override Vector3 GetForward(IGUIState guiState, int index) + { + if (forward != null) + return forward(index); + + return base.GetForward(guiState, index); + } + + protected override Vector3 GetUp(IGUIState guiState, int index) + { + if (up != null) + return up(index); + + return base.GetUp(guiState, index); + } + + protected override Vector3 GetRight(IGUIState guiState, int index) + { + if (right != null) + return right(index); + + return base.GetRight(guiState, index); + } + + protected override object GetUserData(IGUIState guiState, int index) + { + if (userData != null) + return userData(index); + + return base.GetUserData(guiState, index); + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs.meta index 601e95b..2902baf 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/GenericControl.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: ee0367e6650738343b9389aed8aef056 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ee0367e6650738343b9389aed8aef056 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs b/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs index 077fb9b..892dca6 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs @@ -1,58 +1,58 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class GenericDefaultControl : DefaultControl - { - public Func position; - public Func forward; - public Func up; - public Func right; - public Func userData = null; - - public GenericDefaultControl(string name) : base(name) - { - } - - protected override Vector3 GetPosition(IGUIState guiState, int index) - { - if (position != null) - return position(guiState); - - return base.GetPosition(guiState, index); - } - - protected override Vector3 GetForward(IGUIState guiState, int index) - { - if (forward != null) - return forward(guiState); - - return base.GetForward(guiState, index); - } - - protected override Vector3 GetUp(IGUIState guiState, int index) - { - if (up != null) - return up(guiState); - - return base.GetUp(guiState, index); - } - - protected override Vector3 GetRight(IGUIState guiState, int index) - { - if (right != null) - return right(guiState); - - return base.GetRight(guiState, index); - } - - protected override object GetUserData(IGUIState guiState, int index) - { - if (userData != null) - return userData(guiState); - - return base.GetUserData(guiState, index); - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class GenericDefaultControl : DefaultControl + { + public Func position; + public Func forward; + public Func up; + public Func right; + public Func userData = null; + + public GenericDefaultControl(string name) : base(name) + { + } + + protected override Vector3 GetPosition(IGUIState guiState, int index) + { + if (position != null) + return position(guiState); + + return base.GetPosition(guiState, index); + } + + protected override Vector3 GetForward(IGUIState guiState, int index) + { + if (forward != null) + return forward(guiState); + + return base.GetForward(guiState, index); + } + + protected override Vector3 GetUp(IGUIState guiState, int index) + { + if (up != null) + return up(guiState); + + return base.GetUp(guiState, index); + } + + protected override Vector3 GetRight(IGUIState guiState, int index) + { + if (right != null) + return right(guiState); + + return base.GetRight(guiState, index); + } + + protected override object GetUserData(IGUIState guiState, int index) + { + if (userData != null) + return userData(guiState); + + return base.GetUserData(guiState, index); + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs.meta index 2c2b340..6fdb253 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/GenericDefaultControl.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: c6a63895712373a4d9d9538651d9e23e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c6a63895712373a4d9d9538651d9e23e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs b/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs index 27fb92b..59d885e 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs @@ -1,30 +1,30 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal abstract class HoveredControlAction : GUIAction - { - private Control m_HoveredControl; - - public Control hoveredControl - { - get { return m_HoveredControl; } - } - - public HoveredControlAction(Control control) - { - m_HoveredControl = control; - } - - protected override bool CanTrigger(IGUIState guiState) - { - return guiState.nearestControl == hoveredControl.ID; - } - - protected override void OnTrigger(IGUIState guiState) - { - m_HoveredControl.SetActionID(ID); - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal abstract class HoveredControlAction : GUIAction + { + private Control m_HoveredControl; + + public Control hoveredControl + { + get { return m_HoveredControl; } + } + + public HoveredControlAction(Control control) + { + m_HoveredControl = control; + } + + protected override bool CanTrigger(IGUIState guiState) + { + return guiState.nearestControl == hoveredControl.ID; + } + + protected override void OnTrigger(IGUIState guiState) + { + m_HoveredControl.SetActionID(ID); + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs.meta index 2539c9a..8b2387b 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/HoveredControlAction.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 55d754c57ee8db449809b81690cce672 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 55d754c57ee8db449809b81690cce672 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs b/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs index 6a535dc..70de7c2 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs @@ -1,43 +1,43 @@ -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal struct SliderData - { - public Vector3 position; - public Vector3 forward; - public Vector3 up; - public Vector3 right; - - public static readonly SliderData zero = new SliderData() { position = Vector3.zero, forward = Vector3.forward, up = Vector3.up, right = Vector3.right }; - } - - internal interface IGUIState - { - Vector2 mousePosition { get; } - int mouseButton { get; } - int clickCount { get; } - bool isShiftDown { get; } - bool isAltDown { get; } - bool isActionKeyDown { get; } - KeyCode keyCode { get; } - EventType eventType { get; } - string commandName { get; } - int nearestControl { get; set; } - int hotControl { get; set; } - bool changed { get; set; } - int GetControlID(int hint, FocusType focusType); - void AddControl(int controlID, float distance); - bool Slider(int id, SliderData sliderData, out Vector3 newPosition); - void UseCurrentEvent(); - void Repaint(); - bool IsEventOutsideWindow(); - bool IsViewToolActive(); - bool HasCurrentCamera(); - float GetHandleSize(Vector3 position); - float DistanceToSegment(Vector3 p1, Vector3 p2); - float DistanceToCircle(Vector3 center, float radius); - Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos); - } -} +using UnityEngine; +using UnityEditor; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal struct SliderData + { + public Vector3 position; + public Vector3 forward; + public Vector3 up; + public Vector3 right; + + public static readonly SliderData zero = new SliderData() { position = Vector3.zero, forward = Vector3.forward, up = Vector3.up, right = Vector3.right }; + } + + internal interface IGUIState + { + Vector2 mousePosition { get; } + int mouseButton { get; } + int clickCount { get; } + bool isShiftDown { get; } + bool isAltDown { get; } + bool isActionKeyDown { get; } + KeyCode keyCode { get; } + EventType eventType { get; } + string commandName { get; } + int nearestControl { get; set; } + int hotControl { get; set; } + bool changed { get; set; } + int GetControlID(int hint, FocusType focusType); + void AddControl(int controlID, float distance); + bool Slider(int id, SliderData sliderData, out Vector3 newPosition); + void UseCurrentEvent(); + void Repaint(); + bool IsEventOutsideWindow(); + bool IsViewToolActive(); + bool HasCurrentCamera(); + float GetHandleSize(Vector3 position); + float DistanceToSegment(Vector3 p1, Vector3 p2); + float DistanceToCircle(Vector3 center, float radius); + Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos); + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs.meta index cc06d94..b9dc299 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/IGUIState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 6be1960a7dd748d4ebecdfb9d4dab977 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 6be1960a7dd748d4ebecdfb9d4dab977 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs b/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs index 5148947..57b75f2 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs @@ -1,25 +1,25 @@ -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal struct LayoutData - { - public int index; - public float distance; - public Vector3 position; - public Vector3 forward; - public Vector3 up; - public Vector3 right; - public object userData; - - public static readonly LayoutData zero = new LayoutData() { index = 0, distance = float.MaxValue, position = Vector3.zero, forward = Vector3.forward, up = Vector3.up, right = Vector3.right }; - - public static LayoutData Nearest(LayoutData currentData, LayoutData newData) - { - if (newData.distance <= currentData.distance) - return newData; - - return currentData; - } - } -} +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal struct LayoutData + { + public int index; + public float distance; + public Vector3 position; + public Vector3 forward; + public Vector3 up; + public Vector3 right; + public object userData; + + public static readonly LayoutData zero = new LayoutData() { index = 0, distance = float.MaxValue, position = Vector3.zero, forward = Vector3.forward, up = Vector3.up, right = Vector3.right }; + + public static LayoutData Nearest(LayoutData currentData, LayoutData newData) + { + if (newData.distance <= currentData.distance) + return newData; + + return currentData; + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs.meta index 114440e..dea85ad 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/LayoutData.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 430b31d486b6c21429ff2ff02c12dfee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 430b31d486b6c21429ff2ff02c12dfee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs b/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs index c476919..3ed72f9 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs +++ b/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs @@ -1,60 +1,59 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework -{ - internal class SliderAction : ClickAction - { - private SliderData m_SliderData; - - public Action onSliderBegin; - public Action onSliderChanged; - public Action onSliderEnd; - - public SliderAction(Control control) : base(control, 0, false) - { - } - - protected override bool GetFinishContidtion(IGUIState guiState) - { - return guiState.eventType == EventType.MouseUp && guiState.mouseButton == 0; - } - - - protected override void OnTrigger(IGUIState guiState) - { - base.OnTrigger(guiState); - - m_SliderData.position = hoveredControl.hotLayoutData.position; - m_SliderData.forward = hoveredControl.hotLayoutData.forward; - m_SliderData.right = hoveredControl.hotLayoutData.right; - m_SliderData.up = hoveredControl.hotLayoutData.up; - - if (onSliderBegin != null) - onSliderBegin(guiState, hoveredControl, m_SliderData.position); - } - - protected override void OnFinish(IGUIState guiState) - { - if (onSliderEnd != null) - onSliderEnd(guiState, hoveredControl, m_SliderData.position); - - guiState.UseCurrentEvent(); - guiState.Repaint(); - } - - protected override void OnPerform(IGUIState guiState) - { - Vector3 newPosition; - var changed = guiState.Slider(ID, m_SliderData, out newPosition); - - if (changed) - { - m_SliderData.position = newPosition; - - if (onSliderChanged != null) - onSliderChanged(guiState, hoveredControl, newPosition); - } - } - } -} +using System; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D.GUIFramework +{ + internal class SliderAction : ClickAction + { + private SliderData m_SliderData; + + public Action onSliderBegin; + public Action onSliderChanged; + public Action onSliderEnd; + + public SliderAction(Control control) : base(control, 0, false) + { + } + + protected override bool GetFinishContidtion(IGUIState guiState) + { + return guiState.eventType == EventType.MouseUp && guiState.mouseButton == 0; + } + + protected override void OnTrigger(IGUIState guiState) + { + base.OnTrigger(guiState); + + m_SliderData.position = hoveredControl.hotLayoutData.position; + m_SliderData.forward = hoveredControl.hotLayoutData.forward; + m_SliderData.right = hoveredControl.hotLayoutData.right; + m_SliderData.up = hoveredControl.hotLayoutData.up; + + if (onSliderBegin != null) + onSliderBegin(guiState, hoveredControl, m_SliderData.position); + } + + protected override void OnFinish(IGUIState guiState) + { + if (onSliderEnd != null) + onSliderEnd(guiState, hoveredControl, m_SliderData.position); + + guiState.UseCurrentEvent(); + guiState.Repaint(); + } + + protected override void OnPerform(IGUIState guiState) + { + Vector3 newPosition; + var changed = guiState.Slider(ID, m_SliderData, out newPosition); + + if (changed) + { + m_SliderData.position = newPosition; + + if (onSliderChanged != null) + onSliderChanged(guiState, hoveredControl, newPosition); + } + } + } +} diff --git a/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs.meta b/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs.meta index 0c8db0c..e7acec6 100644 --- a/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs.meta +++ b/Editor/2D/ShapeEditor/GUIFramework/SliderAction.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 2a4ac6b059467af44892cccf670f1413 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 2a4ac6b059467af44892cccf670f1413 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources.meta b/Editor/2D/ShapeEditor/Resources.meta index 45182d1..84a86da 100644 --- a/Editor/2D/ShapeEditor/Resources.meta +++ b/Editor/2D/ShapeEditor/Resources.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 6f54797850e5bef43a27f024efe3f96e -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 6f54797850e5bef43a27f024efe3f96e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path.meta b/Editor/2D/ShapeEditor/Resources/Path.meta index ea67125..9513c8c 100644 --- a/Editor/2D/ShapeEditor/Resources/Path.meta +++ b/Editor/2D/ShapeEditor/Resources/Path.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: da71bdc9e230bce449157ba7f69277ec -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: da71bdc9e230bce449157ba7f69277ec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path/pointHovered.png.meta b/Editor/2D/ShapeEditor/Resources/Path/pointHovered.png.meta index 1478663..69b58a6 100644 --- a/Editor/2D/ShapeEditor/Resources/Path/pointHovered.png.meta +++ b/Editor/2D/ShapeEditor/Resources/Path/pointHovered.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 40985c36b6cc53f4a949889c3a3e2f90 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 40985c36b6cc53f4a949889c3a3e2f90 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path/pointNormal.png.meta b/Editor/2D/ShapeEditor/Resources/Path/pointNormal.png.meta index d4aa398..fb301dc 100644 --- a/Editor/2D/ShapeEditor/Resources/Path/pointNormal.png.meta +++ b/Editor/2D/ShapeEditor/Resources/Path/pointNormal.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: f66f743b1d8e82f44a027852526a2b93 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f66f743b1d8e82f44a027852526a2b93 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path/pointPreview.png.meta b/Editor/2D/ShapeEditor/Resources/Path/pointPreview.png.meta index 16091f6..8242b2c 100644 --- a/Editor/2D/ShapeEditor/Resources/Path/pointPreview.png.meta +++ b/Editor/2D/ShapeEditor/Resources/Path/pointPreview.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 6420d2b2a65130f4396f11f0a46d8c2e -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 6420d2b2a65130f4396f11f0a46d8c2e +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path/pointRemovePreview.png.meta b/Editor/2D/ShapeEditor/Resources/Path/pointRemovePreview.png.meta index a4cffb6..4cf25da 100644 --- a/Editor/2D/ShapeEditor/Resources/Path/pointRemovePreview.png.meta +++ b/Editor/2D/ShapeEditor/Resources/Path/pointRemovePreview.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 91da11e81541eec4e8b125dbf7ac18fe -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 91da11e81541eec4e8b125dbf7ac18fe +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path/pointSelected.png.meta b/Editor/2D/ShapeEditor/Resources/Path/pointSelected.png.meta index 3c948ca..b4ea69e 100644 --- a/Editor/2D/ShapeEditor/Resources/Path/pointSelected.png.meta +++ b/Editor/2D/ShapeEditor/Resources/Path/pointSelected.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 826595754b0623345a972ceb7f0d16c5 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 826595754b0623345a972ceb7f0d16c5 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/Path/tangentNormal.png.meta b/Editor/2D/ShapeEditor/Resources/Path/tangentNormal.png.meta index e4aedcd..d529d2f 100644 --- a/Editor/2D/ShapeEditor/Resources/Path/tangentNormal.png.meta +++ b/Editor/2D/ShapeEditor/Resources/Path/tangentNormal.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 02831714bf266174cbf2a363196c49dc -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 02831714bf266174cbf2a363196c49dc +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/ShapeTool.png.meta b/Editor/2D/ShapeEditor/Resources/ShapeTool.png.meta index 2c8c736..a3abe1d 100644 --- a/Editor/2D/ShapeEditor/Resources/ShapeTool.png.meta +++ b/Editor/2D/ShapeEditor/Resources/ShapeTool.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 357468e90e97b1f48af3e576fd164ceb -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 357468e90e97b1f48af3e576fd164ceb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/ShapeToolPro.png.meta b/Editor/2D/ShapeEditor/Resources/ShapeToolPro.png.meta index aa773a7..67cd495 100644 --- a/Editor/2D/ShapeEditor/Resources/ShapeToolPro.png.meta +++ b/Editor/2D/ShapeEditor/Resources/ShapeToolPro.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: fdee5855bd8fd6841bd4d01b0bbeedc3 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: fdee5855bd8fd6841bd4d01b0bbeedc3 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/TangentBroken.png.meta b/Editor/2D/ShapeEditor/Resources/TangentBroken.png.meta index 3b1d6c9..188fb69 100644 --- a/Editor/2D/ShapeEditor/Resources/TangentBroken.png.meta +++ b/Editor/2D/ShapeEditor/Resources/TangentBroken.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: cdf84f3eb174395469aa10a6cf7b04a7 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: cdf84f3eb174395469aa10a6cf7b04a7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/TangentBrokenPro.png.meta b/Editor/2D/ShapeEditor/Resources/TangentBrokenPro.png.meta index ab54c9b..998cc56 100644 --- a/Editor/2D/ShapeEditor/Resources/TangentBrokenPro.png.meta +++ b/Editor/2D/ShapeEditor/Resources/TangentBrokenPro.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: bf2498e489f73d547aafc73fd66a36cb -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: bf2498e489f73d547aafc73fd66a36cb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/TangentContinuous.png.meta b/Editor/2D/ShapeEditor/Resources/TangentContinuous.png.meta index 9f98921..df497e7 100644 --- a/Editor/2D/ShapeEditor/Resources/TangentContinuous.png.meta +++ b/Editor/2D/ShapeEditor/Resources/TangentContinuous.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: f3d009ca5277c90499f90541e08d8021 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f3d009ca5277c90499f90541e08d8021 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/TangentContinuousPro.png.meta b/Editor/2D/ShapeEditor/Resources/TangentContinuousPro.png.meta index fc8a0ae..c74de34 100644 --- a/Editor/2D/ShapeEditor/Resources/TangentContinuousPro.png.meta +++ b/Editor/2D/ShapeEditor/Resources/TangentContinuousPro.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 071cd56d8f85dc247838300862f43e2f -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 071cd56d8f85dc247838300862f43e2f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/TangentLinear.png.meta b/Editor/2D/ShapeEditor/Resources/TangentLinear.png.meta index 776ce2e..5e614b1 100644 --- a/Editor/2D/ShapeEditor/Resources/TangentLinear.png.meta +++ b/Editor/2D/ShapeEditor/Resources/TangentLinear.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 4867cb38cc0872c45b205c593c4ce5c0 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 4867cb38cc0872c45b205c593c4ce5c0 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Resources/TangentLinearPro.png.meta b/Editor/2D/ShapeEditor/Resources/TangentLinearPro.png.meta index 3d79928..5e275c9 100644 --- a/Editor/2D/ShapeEditor/Resources/TangentLinearPro.png.meta +++ b/Editor/2D/ShapeEditor/Resources/TangentLinearPro.png.meta @@ -1,139 +1,139 @@ -fileFormatVersion: 2 -guid: 2ce62e9a7e0a56844bf0b342840bbdf7 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - 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 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: 2 - mipBias: -100 - 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 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Windows Store Apps - maxTextureSize: 8192 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 2ce62e9a7e0a56844bf0b342840bbdf7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 2 + mipBias: -100 + 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 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 8192 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection.meta b/Editor/2D/ShapeEditor/Selection.meta index 0229aea..98eb4d6 100644 --- a/Editor/2D/ShapeEditor/Selection.meta +++ b/Editor/2D/ShapeEditor/Selection.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: e37e3e6c318ce764b916b72b7d686499 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e37e3e6c318ce764b916b72b7d686499 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/ISelectable.cs b/Editor/2D/ShapeEditor/Selection/ISelectable.cs index 87c2254..7160a84 100644 --- a/Editor/2D/ShapeEditor/Selection/ISelectable.cs +++ b/Editor/2D/ShapeEditor/Selection/ISelectable.cs @@ -1,7 +1,7 @@ -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface ISelectable - { - bool Select(ISelector selector); - } -} +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface ISelectable + { + bool Select(ISelector selector); + } +} diff --git a/Editor/2D/ShapeEditor/Selection/ISelectable.cs.meta b/Editor/2D/ShapeEditor/Selection/ISelectable.cs.meta index f4e44ab..cc0be41 100644 --- a/Editor/2D/ShapeEditor/Selection/ISelectable.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/ISelectable.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 1eb4ddab2e7330247a36de2d5c793274 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 1eb4ddab2e7330247a36de2d5c793274 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/ISelection.cs b/Editor/2D/ShapeEditor/Selection/ISelection.cs index 859b98f..4c5f30d 100644 --- a/Editor/2D/ShapeEditor/Selection/ISelection.cs +++ b/Editor/2D/ShapeEditor/Selection/ISelection.cs @@ -1,16 +1,16 @@ -using System.Collections.Generic; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface ISelection - { - int Count { get; } - T activeElement { get; set; } - T[] elements { get; set; } - void Clear(); - void BeginSelection(); - void EndSelection(bool select); - bool Select(T element, bool select); - bool Contains(T element); - } -} +using System.Collections.Generic; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface ISelection + { + int Count { get; } + T activeElement { get; set; } + T[] elements { get; set; } + void Clear(); + void BeginSelection(); + void EndSelection(bool select); + bool Select(T element, bool select); + bool Contains(T element); + } +} diff --git a/Editor/2D/ShapeEditor/Selection/ISelection.cs.meta b/Editor/2D/ShapeEditor/Selection/ISelection.cs.meta index 8a9e3b4..36407c5 100644 --- a/Editor/2D/ShapeEditor/Selection/ISelection.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/ISelection.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: f1dff44bf58760a4ab5b35e9abc5a8f4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f1dff44bf58760a4ab5b35e9abc5a8f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/ISelector.cs b/Editor/2D/ShapeEditor/Selection/ISelector.cs index e038c0d..0ab98fd 100644 --- a/Editor/2D/ShapeEditor/Selection/ISelector.cs +++ b/Editor/2D/ShapeEditor/Selection/ISelector.cs @@ -1,7 +1,7 @@ -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface ISelector - { - bool Select(T element); - } -} +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface ISelector + { + bool Select(T element); + } +} diff --git a/Editor/2D/ShapeEditor/Selection/ISelector.cs.meta b/Editor/2D/ShapeEditor/Selection/ISelector.cs.meta index f3357af..c89a71d 100644 --- a/Editor/2D/ShapeEditor/Selection/ISelector.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/ISelector.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: af57b062bcd7c24499e425360e7fd03a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: af57b062bcd7c24499e425360e7fd03a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs b/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs index 53091d1..fa4aa61 100644 --- a/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs +++ b/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs @@ -1,13 +1,13 @@ -using UnityEngine; -using System; -using System.Collections; -using System.Collections.Generic; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - [Serializable] - internal class IndexedSelection : SerializableSelection - { - protected override int GetInvalidElement() { return -1; } - } -} +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + [Serializable] + internal class IndexedSelection : SerializableSelection + { + protected override int GetInvalidElement() { return -1; } + } +} diff --git a/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs.meta b/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs.meta index fac384f..83ced7b 100644 --- a/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/IndexedSelection.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 43bf9a413ecb3fb459c17274518637b8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 43bf9a413ecb3fb459c17274518637b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs b/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs index 1759a01..8a4fb4f 100644 --- a/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs +++ b/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs @@ -1,13 +1,13 @@ -using UnityEngine; -using UnityEditor; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class PointRectSelector : RectSelector - { - protected override bool Select(Vector3 element) - { - return guiRect.Contains(HandleUtility.WorldToGUIPoint(element), true); - } - } -} +using UnityEngine; +using UnityEditor; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class PointRectSelector : RectSelector + { + protected override bool Select(Vector3 element) + { + return guiRect.Contains(HandleUtility.WorldToGUIPoint(element), true); + } + } +} diff --git a/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs.meta b/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs.meta index dcc4aab..d1ec53b 100644 --- a/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/PointRectSelector.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 9eeddcfd48b29724589aae6e5b7881c1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 9eeddcfd48b29724589aae6e5b7881c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/RectSelector.cs b/Editor/2D/ShapeEditor/Selection/RectSelector.cs index cd56582..394377a 100644 --- a/Editor/2D/ShapeEditor/Selection/RectSelector.cs +++ b/Editor/2D/ShapeEditor/Selection/RectSelector.cs @@ -1,150 +1,150 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal abstract class RectSelector : ISelector - { - public Action, bool> onSelectionBegin; - public Action> onSelectionChanged; - public Action> onSelectionEnd = null; - - private GUISystem m_GUISystem; - private Control m_RectSelectorControl; - private GUIAction m_RectSelectAction; - private Vector3 m_RectStart; - private Vector3 m_RectEnd; - private Rect m_GUIRect; - private IDrawer m_Drawer = new Drawer(); - - public Rect guiRect - { - get { return m_GUIRect; } - } - - public RectSelector() : this(new GUISystem(new GUIState())) { } - - public RectSelector(GUISystem guiSystem) - { - m_GUISystem = guiSystem; - - m_RectSelectorControl = new GenericDefaultControl("RectSelector") - { - position = (guiState) => - { - return GUIToWorld(guiState, guiState.mousePosition); - }, - forward = (guiState) => - { - if (Camera.current) - return Camera.current.transform.forward; - - return Vector3.forward; - }, - right = (guiState) => - { - if (Camera.current) - return Camera.current.transform.right; - - return Vector3.right; - }, - up = (guiState) => - { - if (Camera.current) - return Camera.current.transform.up; - - return Vector3.up; - } - }; - - m_RectSelectAction = new SliderAction(m_RectSelectorControl) - { - enableRepaint = (guiState, action) => - { - var size = m_RectStart - m_RectEnd; - return size != Vector3.zero && guiState.hotControl == action.ID; - }, - onClick = (guiState, control) => - { - m_RectStart = GUIToWorld(guiState, guiState.mousePosition); - m_RectEnd = m_RectStart; - m_GUIRect = CalculateGUIRect(); - }, - onSliderBegin = (guiState, control, position) => - { - m_RectEnd = position; - m_GUIRect = CalculateGUIRect(); - - if (onSelectionBegin != null) - onSelectionBegin(this, guiState.isShiftDown); - }, - onSliderChanged = (guiState, control, position) => - { - m_RectEnd = position; - m_GUIRect = CalculateGUIRect(); - - if (onSelectionChanged != null) - onSelectionChanged(this); - }, - onSliderEnd = (guiState, control, position) => - { - if (onSelectionEnd != null) - onSelectionEnd(this); - }, - onRepaint = (guiState, action) => - { - m_Drawer.DrawSelectionRect(m_GUIRect); - } - }; - - m_GUISystem.AddControl(m_RectSelectorControl); - m_GUISystem.AddAction(m_RectSelectAction); - } - - private Vector3 GUIToWorld(IGUIState guiState, Vector2 guiPosition) - { - var forward = Vector3.forward; - - if (guiState.HasCurrentCamera()) - forward = Camera.current.transform.forward; - - return guiState.GUIToWorld(guiPosition, forward, Vector3.zero); - } - - private Rect CalculateGUIRect() - { - return FromToRect(HandleUtility.WorldToGUIPoint(m_RectStart), HandleUtility.WorldToGUIPoint(m_RectEnd)); - } - - private Rect FromToRect(Vector2 start, Vector2 end) - { - Rect r = new Rect(start.x, start.y, end.x - start.x, end.y - start.y); - if (r.width < 0) - { - r.x += r.width; - r.width = -r.width; - } - if (r.height < 0) - { - r.y += r.height; - r.height = -r.height; - } - return r; - } - - public void OnGUI() - { - m_GUISystem.OnGUI(); - } - - bool ISelector.Select(T element) - { - return Select(element); - } - - protected abstract bool Select(T element); - } -} +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal abstract class RectSelector : ISelector + { + public Action, bool> onSelectionBegin; + public Action> onSelectionChanged; + public Action> onSelectionEnd = null; + + private GUISystem m_GUISystem; + private Control m_RectSelectorControl; + private GUIAction m_RectSelectAction; + private Vector3 m_RectStart; + private Vector3 m_RectEnd; + private Rect m_GUIRect; + private IDrawer m_Drawer = new Drawer(); + + public Rect guiRect + { + get { return m_GUIRect; } + } + + public RectSelector() : this(new GUISystem(new GUIState())) { } + + public RectSelector(GUISystem guiSystem) + { + m_GUISystem = guiSystem; + + m_RectSelectorControl = new GenericDefaultControl("RectSelector") + { + position = (guiState) => + { + return GUIToWorld(guiState, guiState.mousePosition); + }, + forward = (guiState) => + { + if (Camera.current) + return Camera.current.transform.forward; + + return Vector3.forward; + }, + right = (guiState) => + { + if (Camera.current) + return Camera.current.transform.right; + + return Vector3.right; + }, + up = (guiState) => + { + if (Camera.current) + return Camera.current.transform.up; + + return Vector3.up; + } + }; + + m_RectSelectAction = new SliderAction(m_RectSelectorControl) + { + enableRepaint = (guiState, action) => + { + var size = m_RectStart - m_RectEnd; + return size != Vector3.zero && guiState.hotControl == action.ID; + }, + onClick = (guiState, control) => + { + m_RectStart = GUIToWorld(guiState, guiState.mousePosition); + m_RectEnd = m_RectStart; + m_GUIRect = CalculateGUIRect(); + }, + onSliderBegin = (guiState, control, position) => + { + m_RectEnd = position; + m_GUIRect = CalculateGUIRect(); + + if (onSelectionBegin != null) + onSelectionBegin(this, guiState.isShiftDown); + }, + onSliderChanged = (guiState, control, position) => + { + m_RectEnd = position; + m_GUIRect = CalculateGUIRect(); + + if (onSelectionChanged != null) + onSelectionChanged(this); + }, + onSliderEnd = (guiState, control, position) => + { + if (onSelectionEnd != null) + onSelectionEnd(this); + }, + onRepaint = (guiState, action) => + { + m_Drawer.DrawSelectionRect(m_GUIRect); + } + }; + + m_GUISystem.AddControl(m_RectSelectorControl); + m_GUISystem.AddAction(m_RectSelectAction); + } + + private Vector3 GUIToWorld(IGUIState guiState, Vector2 guiPosition) + { + var forward = Vector3.forward; + + if (guiState.HasCurrentCamera()) + forward = Camera.current.transform.forward; + + return guiState.GUIToWorld(guiPosition, forward, Vector3.zero); + } + + private Rect CalculateGUIRect() + { + return FromToRect(HandleUtility.WorldToGUIPoint(m_RectStart), HandleUtility.WorldToGUIPoint(m_RectEnd)); + } + + private Rect FromToRect(Vector2 start, Vector2 end) + { + Rect r = new Rect(start.x, start.y, end.x - start.x, end.y - start.y); + if (r.width < 0) + { + r.x += r.width; + r.width = -r.width; + } + if (r.height < 0) + { + r.y += r.height; + r.height = -r.height; + } + return r; + } + + public void OnGUI() + { + m_GUISystem.OnGUI(); + } + + bool ISelector.Select(T element) + { + return Select(element); + } + + protected abstract bool Select(T element); + } +} diff --git a/Editor/2D/ShapeEditor/Selection/RectSelector.cs.meta b/Editor/2D/ShapeEditor/Selection/RectSelector.cs.meta index 31344fd..98bedb7 100644 --- a/Editor/2D/ShapeEditor/Selection/RectSelector.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/RectSelector.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 5219fa5884eea3d409b999f55740f2ba -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 5219fa5884eea3d409b999f55740f2ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs b/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs index d4d50b9..fb6e66b 100644 --- a/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs +++ b/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs @@ -1,143 +1,143 @@ -using UnityEngine; -using System; -using System.Collections; -using System.Collections.Generic; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - [Serializable] - internal abstract class SerializableSelection : ISelection, ISerializationCallbackReceiver - { - internal readonly static int kInvalidID = -1; - - [SerializeField] - private T[] m_Keys = new T[0]; - - private HashSet m_Selection = new HashSet(); - private HashSet m_TemporalSelection = new HashSet(); - private bool m_SelectionInProgress = false; - - public int Count - { - get { return m_Selection.Count + m_TemporalSelection.Count; } - } - - public T activeElement - { - get { return First(); } - set - { - Clear(); - Select(value, true); - } - } - - public T[] elements - { - get - { - var set = m_Selection; - - if (m_SelectionInProgress) - { - var union = new HashSet(m_Selection); - union.UnionWith(m_TemporalSelection); - set = union; - } - - return new List(set).ToArray(); - } - set - { - Clear(); - foreach(var element in value) - Select(element, true); - } - } - - protected abstract T GetInvalidElement(); - - public void Clear() - { - GetSelection().Clear(); - } - - public void BeginSelection() - { - m_SelectionInProgress = true; - Clear(); - } - - public void EndSelection(bool select) - { - m_SelectionInProgress = false; - - if (select) - m_Selection.UnionWith(m_TemporalSelection); - else - m_Selection.ExceptWith(m_TemporalSelection); - - m_TemporalSelection.Clear(); - } - - public bool Select(T element, bool select) - { - var changed = false; - - if(EqualityComparer.Default.Equals(element, GetInvalidElement())) - return changed; - - if (select) - changed = GetSelection().Add(element); - else if (Contains(element)) - changed = GetSelection().Remove(element); - - return changed; - } - - public bool Contains(T element) - { - return m_Selection.Contains(element) || m_TemporalSelection.Contains(element); - } - - private HashSet GetSelection() - { - if (m_SelectionInProgress) - return m_TemporalSelection; - - return m_Selection; - } - - private T First() - { - T element = First(m_Selection); - - if(EqualityComparer.Default.Equals(element, GetInvalidElement())) - element = First(m_TemporalSelection); - - return element; - } - - private T First(HashSet set) - { - if(set.Count == 0) - return GetInvalidElement(); - - using (var enumerator = set.GetEnumerator()) - { - Debug.Assert(enumerator.MoveNext()); - return enumerator.Current; - } - } - - void ISerializationCallbackReceiver.OnBeforeSerialize() - { - m_Keys = new List(m_Selection).ToArray(); - } - - void ISerializationCallbackReceiver.OnAfterDeserialize() - { - elements = m_Keys; - } - } -} +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + [Serializable] + internal abstract class SerializableSelection : ISelection, ISerializationCallbackReceiver + { + internal readonly static int kInvalidID = -1; + + [SerializeField] + private T[] m_Keys = new T[0]; + + private HashSet m_Selection = new HashSet(); + private HashSet m_TemporalSelection = new HashSet(); + private bool m_SelectionInProgress = false; + + public int Count + { + get { return m_Selection.Count + m_TemporalSelection.Count; } + } + + public T activeElement + { + get { return First(); } + set + { + Clear(); + Select(value, true); + } + } + + public T[] elements + { + get + { + var set = m_Selection; + + if (m_SelectionInProgress) + { + var union = new HashSet(m_Selection); + union.UnionWith(m_TemporalSelection); + set = union; + } + + return new List(set).ToArray(); + } + set + { + Clear(); + foreach (var element in value) + Select(element, true); + } + } + + protected abstract T GetInvalidElement(); + + public void Clear() + { + GetSelection().Clear(); + } + + public void BeginSelection() + { + m_SelectionInProgress = true; + Clear(); + } + + public void EndSelection(bool select) + { + m_SelectionInProgress = false; + + if (select) + m_Selection.UnionWith(m_TemporalSelection); + else + m_Selection.ExceptWith(m_TemporalSelection); + + m_TemporalSelection.Clear(); + } + + public bool Select(T element, bool select) + { + var changed = false; + + if (EqualityComparer.Default.Equals(element, GetInvalidElement())) + return changed; + + if (select) + changed = GetSelection().Add(element); + else if (Contains(element)) + changed = GetSelection().Remove(element); + + return changed; + } + + public bool Contains(T element) + { + return m_Selection.Contains(element) || m_TemporalSelection.Contains(element); + } + + private HashSet GetSelection() + { + if (m_SelectionInProgress) + return m_TemporalSelection; + + return m_Selection; + } + + private T First() + { + T element = First(m_Selection); + + if (EqualityComparer.Default.Equals(element, GetInvalidElement())) + element = First(m_TemporalSelection); + + return element; + } + + private T First(HashSet set) + { + if (set.Count == 0) + return GetInvalidElement(); + + using (var enumerator = set.GetEnumerator()) + { + Debug.Assert(enumerator.MoveNext()); + return enumerator.Current; + } + } + + void ISerializationCallbackReceiver.OnBeforeSerialize() + { + m_Keys = new List(m_Selection).ToArray(); + } + + void ISerializationCallbackReceiver.OnAfterDeserialize() + { + elements = m_Keys; + } + } +} diff --git a/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs.meta b/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs.meta index 3eec6fb..3bc60eb 100644 --- a/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs.meta +++ b/Editor/2D/ShapeEditor/Selection/SerializableSelection.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: f39217979d4f8a44d98271a6eb75e981 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f39217979d4f8a44d98271a6eb75e981 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Shapes.meta b/Editor/2D/ShapeEditor/Shapes.meta index 3926b6b..12c3a89 100644 --- a/Editor/2D/ShapeEditor/Shapes.meta +++ b/Editor/2D/ShapeEditor/Shapes.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: c46211b00cbdbe2498ffac5f139e2454 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c46211b00cbdbe2498ffac5f139e2454 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Shapes/IShape.cs b/Editor/2D/ShapeEditor/Shapes/IShape.cs index 35d5f68..f404109 100644 --- a/Editor/2D/ShapeEditor/Shapes/IShape.cs +++ b/Editor/2D/ShapeEditor/Shapes/IShape.cs @@ -1,19 +1,19 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal enum ShapeType - { - Polygon, - Spline - } - - internal interface IShape - { - ShapeType type { get; } - bool isOpenEnded { get; } - ControlPoint[] ToControlPoints(); - } -} +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal enum ShapeType + { + Polygon, + Spline + } + + internal interface IShape + { + ShapeType type { get; } + bool isOpenEnded { get; } + ControlPoint[] ToControlPoints(); + } +} diff --git a/Editor/2D/ShapeEditor/Shapes/IShape.cs.meta b/Editor/2D/ShapeEditor/Shapes/IShape.cs.meta index e89f914..2b0161e 100644 --- a/Editor/2D/ShapeEditor/Shapes/IShape.cs.meta +++ b/Editor/2D/ShapeEditor/Shapes/IShape.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 97901fc1ca143f445a68b5b1a0922bc7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 97901fc1ca143f445a68b5b1a0922bc7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Shapes/Polygon.cs b/Editor/2D/ShapeEditor/Shapes/Polygon.cs index 4cbb2e0..fcfc942 100644 --- a/Editor/2D/ShapeEditor/Shapes/Polygon.cs +++ b/Editor/2D/ShapeEditor/Shapes/Polygon.cs @@ -1,35 +1,35 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal struct Polygon : IShape - { - public bool isOpenEnded; - - public Vector3[] points; - - ShapeType IShape.type => ShapeType.Polygon; - - bool IShape.isOpenEnded => isOpenEnded; - - ControlPoint[] IShape.ToControlPoints() - { - if (points == null) - throw new NullReferenceException("Points array is null"); - - var controlPoints = new List(); - - foreach (var point in points) - { - controlPoints.Add(new ControlPoint() { position = point }); - } - - return controlPoints.ToArray(); - } - - public static Polygon empty = new Polygon() { isOpenEnded = true, points = new Vector3[0] }; - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal struct Polygon : IShape + { + public bool isOpenEnded; + + public Vector3[] points; + + ShapeType IShape.type => ShapeType.Polygon; + + bool IShape.isOpenEnded => isOpenEnded; + + ControlPoint[] IShape.ToControlPoints() + { + if (points == null) + throw new NullReferenceException("Points array is null"); + + var controlPoints = new List(); + + foreach (var point in points) + { + controlPoints.Add(new ControlPoint() { position = point }); + } + + return controlPoints.ToArray(); + } + + public static Polygon empty = new Polygon() { isOpenEnded = true, points = new Vector3[0] }; + } +} diff --git a/Editor/2D/ShapeEditor/Shapes/Polygon.cs.meta b/Editor/2D/ShapeEditor/Shapes/Polygon.cs.meta index 28e9e67..98764bc 100644 --- a/Editor/2D/ShapeEditor/Shapes/Polygon.cs.meta +++ b/Editor/2D/ShapeEditor/Shapes/Polygon.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: e184e9638bf594e4bbd2e59decedf776 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e184e9638bf594e4bbd2e59decedf776 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs b/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs index e365b19..5de10e2 100644 --- a/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs +++ b/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs @@ -1,102 +1,102 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal static class ShapeExtensions - { - public static Polygon ToPolygon(this Vector3[] points, bool isOpenEnded) - { - return new Polygon() - { - isOpenEnded = isOpenEnded, - points = points - }; - } - - public static Spline ToSpline(this Vector3[] points, bool isOpenEnded) - { - if (!points.IsSpline(isOpenEnded) && points.IsSpline(!isOpenEnded)) - { - var pointList = new List(points); - - if (isOpenEnded) - { - while (pointList.Count % 3 != 1) - pointList.RemoveAt(pointList.Count-1); - - points = pointList.ToArray(); - } - else - { - var last = pointList[pointList.Count-1]; - var first = pointList[0]; - var v = first - last; - - pointList.Add(last + v.normalized * (v.magnitude / 3f)); - pointList.Add(first - v.normalized * (v.magnitude / 3f)); - - points = pointList.ToArray(); - } - } - - if (!points.IsSpline(isOpenEnded)) - throw new Exception("The provided control point array can't conform a Spline."); - - return new Spline() - { - isOpenEnded = isOpenEnded, - points = points - }; - } - - public static bool IsSpline(this Vector3[] points, bool isOpenEnded) - { - if (points.Length < 4) - return false; - - if (isOpenEnded && points.Length % 3 != 1) - return false; - - if (!isOpenEnded && points.Length % 3 != 0) - return false; - - return true; - } - - public static Spline ToSpline(this Polygon polygon) - { - var newPointCount = polygon.points.Length * 3; - - if (polygon.isOpenEnded) - newPointCount = (polygon.points.Length - 1) * 3 + 1; - - var newPoints = new Vector3[newPointCount]; - var controlPoints = polygon.points; - var pointCount = controlPoints.Length; - - for (var i = 0; i < pointCount; ++i) - { - var nextIndex = (i + 1) % pointCount; - var point = controlPoints[i]; - var v = controlPoints[nextIndex] - point; - - newPoints[i * 3] = point; - - if (i * 3 + 2 < newPointCount) - { - newPoints[i * 3 + 1] = point + v / 3f; - newPoints[i * 3 + 2] = point + v * 2f / 3f; - } - } - - return new Spline() - { - isOpenEnded = polygon.isOpenEnded, - points = newPoints - }; - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal static class ShapeExtensions + { + public static Polygon ToPolygon(this Vector3[] points, bool isOpenEnded) + { + return new Polygon() + { + isOpenEnded = isOpenEnded, + points = points + }; + } + + public static Spline ToSpline(this Vector3[] points, bool isOpenEnded) + { + if (!points.IsSpline(isOpenEnded) && points.IsSpline(!isOpenEnded)) + { + var pointList = new List(points); + + if (isOpenEnded) + { + while (pointList.Count % 3 != 1) + pointList.RemoveAt(pointList.Count - 1); + + points = pointList.ToArray(); + } + else + { + var last = pointList[pointList.Count - 1]; + var first = pointList[0]; + var v = first - last; + + pointList.Add(last + v.normalized * (v.magnitude / 3f)); + pointList.Add(first - v.normalized * (v.magnitude / 3f)); + + points = pointList.ToArray(); + } + } + + if (!points.IsSpline(isOpenEnded)) + throw new Exception("The provided control point array can't conform a Spline."); + + return new Spline() + { + isOpenEnded = isOpenEnded, + points = points + }; + } + + public static bool IsSpline(this Vector3[] points, bool isOpenEnded) + { + if (points.Length < 4) + return false; + + if (isOpenEnded && points.Length % 3 != 1) + return false; + + if (!isOpenEnded && points.Length % 3 != 0) + return false; + + return true; + } + + public static Spline ToSpline(this Polygon polygon) + { + var newPointCount = polygon.points.Length * 3; + + if (polygon.isOpenEnded) + newPointCount = (polygon.points.Length - 1) * 3 + 1; + + var newPoints = new Vector3[newPointCount]; + var controlPoints = polygon.points; + var pointCount = controlPoints.Length; + + for (var i = 0; i < pointCount; ++i) + { + var nextIndex = (i + 1) % pointCount; + var point = controlPoints[i]; + var v = controlPoints[nextIndex] - point; + + newPoints[i * 3] = point; + + if (i * 3 + 2 < newPointCount) + { + newPoints[i * 3 + 1] = point + v / 3f; + newPoints[i * 3 + 2] = point + v * 2f / 3f; + } + } + + return new Spline() + { + isOpenEnded = polygon.isOpenEnded, + points = newPoints + }; + } + } +} diff --git a/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs.meta b/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs.meta index 94d457a..7b8b580 100644 --- a/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs.meta +++ b/Editor/2D/ShapeEditor/Shapes/ShapeExtensions.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 75619a6c267af984fb57f4ce5fb7ee29 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 75619a6c267af984fb57f4ce5fb7ee29 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/Shapes/Spline.cs b/Editor/2D/ShapeEditor/Shapes/Spline.cs index 8d9d368..b9d2c75 100644 --- a/Editor/2D/ShapeEditor/Shapes/Spline.cs +++ b/Editor/2D/ShapeEditor/Shapes/Spline.cs @@ -1,102 +1,102 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal struct Spline : IShape - { - public bool isOpenEnded; - - public Vector3[] points; - - ShapeType IShape.type => ShapeType.Spline; - - bool IShape.isOpenEnded => isOpenEnded; - - ControlPoint[] IShape.ToControlPoints() - { - if (points == null) - throw new NullReferenceException("Points array is null"); - - if (!points.IsSpline(isOpenEnded)) - throw new Exception("The provided control point array can't conform a Spline."); - - var controlPoints = new List(); - var leftTangent = Vector3.zero; - var rightTangent = Vector3.zero; - var pointCount = points.Length; - - for (var i = 0; i < pointCount; i += 3) - { - if (i == 0) - { - if (isOpenEnded) - leftTangent = points[0]; - else - leftTangent = points[EditablePathUtility.Mod(-1, pointCount)]; - } - - if (i == pointCount - 1 && isOpenEnded) - rightTangent = points[i]; - else - rightTangent = points[i+1]; - - - controlPoints.Add( - new ControlPoint() - { - position = points[i], - leftTangent = leftTangent, - rightTangent = rightTangent, - tangentMode = TangentMode.Broken - }); - - if (i == pointCount - 1 && isOpenEnded) - leftTangent = Vector3.zero; - else - leftTangent = points[i+2]; - } - - pointCount = controlPoints.Count; - - for (var i = 0; i < pointCount; ++i) - { - var prevIndex = EditablePathUtility.Mod(i-1, pointCount); - var nextIndex = EditablePathUtility.Mod(i+1, pointCount); - var controlPoint = controlPoints[i]; - var prevControlPoint = controlPoints[prevIndex]; - var nextControlPoint = controlPoints[nextIndex]; - - var liniarLeftPosition = (prevControlPoint.position - controlPoint.position) / 3f; - var isLeftTangentLinear = (controlPoint.localLeftTangent - liniarLeftPosition).sqrMagnitude < 0.001f; - - if (isLeftTangentLinear) - controlPoint.localLeftTangent = Vector3.zero; - - var liniarRightPosition = (nextControlPoint.position - controlPoint.position) / 3f; - var isRightTangentLinear = (controlPoint.localRightTangent - liniarRightPosition).sqrMagnitude < 0.001f; - - if (isRightTangentLinear) - controlPoint.localRightTangent = Vector3.zero; - - var tangentDotProduct = Vector3.Dot(controlPoint.localLeftTangent.normalized, controlPoint.localRightTangent.normalized); - var isContinous = tangentDotProduct < 0f && (tangentDotProduct + 1) * (tangentDotProduct + 1) < 0.001f; - - if (isLeftTangentLinear && isRightTangentLinear) - controlPoint.tangentMode = TangentMode.Linear; - else if (isLeftTangentLinear || isRightTangentLinear) - controlPoint.tangentMode = TangentMode.Broken; - else if (isContinous) - controlPoint.tangentMode = TangentMode.Continuous; - - controlPoints[i] = controlPoint; - } - - return controlPoints.ToArray(); - } - - public static Spline empty = new Spline() { isOpenEnded = true, points = new Vector3[0] }; - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal struct Spline : IShape + { + public bool isOpenEnded; + + public Vector3[] points; + + ShapeType IShape.type => ShapeType.Spline; + + bool IShape.isOpenEnded => isOpenEnded; + + ControlPoint[] IShape.ToControlPoints() + { + if (points == null) + throw new NullReferenceException("Points array is null"); + + if (!points.IsSpline(isOpenEnded)) + throw new Exception("The provided control point array can't conform a Spline."); + + var controlPoints = new List(); + var leftTangent = Vector3.zero; + var rightTangent = Vector3.zero; + var pointCount = points.Length; + + for (var i = 0; i < pointCount; i += 3) + { + if (i == 0) + { + if (isOpenEnded) + leftTangent = points[0]; + else + leftTangent = points[EditablePathUtility.Mod(-1, pointCount)]; + } + + if (i == pointCount - 1 && isOpenEnded) + rightTangent = points[i]; + else + rightTangent = points[i + 1]; + + + controlPoints.Add( + new ControlPoint() + { + position = points[i], + leftTangent = leftTangent, + rightTangent = rightTangent, + tangentMode = TangentMode.Broken + }); + + if (i == pointCount - 1 && isOpenEnded) + leftTangent = Vector3.zero; + else + leftTangent = points[i + 2]; + } + + pointCount = controlPoints.Count; + + for (var i = 0; i < pointCount; ++i) + { + var prevIndex = EditablePathUtility.Mod(i - 1, pointCount); + var nextIndex = EditablePathUtility.Mod(i + 1, pointCount); + var controlPoint = controlPoints[i]; + var prevControlPoint = controlPoints[prevIndex]; + var nextControlPoint = controlPoints[nextIndex]; + + var liniarLeftPosition = (prevControlPoint.position - controlPoint.position) / 3f; + var isLeftTangentLinear = (controlPoint.localLeftTangent - liniarLeftPosition).sqrMagnitude < 0.001f; + + if (isLeftTangentLinear) + controlPoint.localLeftTangent = Vector3.zero; + + var liniarRightPosition = (nextControlPoint.position - controlPoint.position) / 3f; + var isRightTangentLinear = (controlPoint.localRightTangent - liniarRightPosition).sqrMagnitude < 0.001f; + + if (isRightTangentLinear) + controlPoint.localRightTangent = Vector3.zero; + + var tangentDotProduct = Vector3.Dot(controlPoint.localLeftTangent.normalized, controlPoint.localRightTangent.normalized); + var isContinous = tangentDotProduct < 0f && (tangentDotProduct + 1) * (tangentDotProduct + 1) < 0.001f; + + if (isLeftTangentLinear && isRightTangentLinear) + controlPoint.tangentMode = TangentMode.Linear; + else if (isLeftTangentLinear || isRightTangentLinear) + controlPoint.tangentMode = TangentMode.Broken; + else if (isContinous) + controlPoint.tangentMode = TangentMode.Continuous; + + controlPoints[i] = controlPoint; + } + + return controlPoints.ToArray(); + } + + public static Spline empty = new Spline() { isOpenEnded = true, points = new Vector3[0] }; + } +} diff --git a/Editor/2D/ShapeEditor/Shapes/Spline.cs.meta b/Editor/2D/ShapeEditor/Shapes/Spline.cs.meta index 6f9ca0e..b821356 100644 --- a/Editor/2D/ShapeEditor/Shapes/Spline.cs.meta +++ b/Editor/2D/ShapeEditor/Shapes/Spline.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: f51e9270a45193942ad7e3daafc2a019 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f51e9270a45193942ad7e3daafc2a019 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/View.meta b/Editor/2D/ShapeEditor/View.meta index 5a8525e..0a72b96 100644 --- a/Editor/2D/ShapeEditor/View.meta +++ b/Editor/2D/ShapeEditor/View.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: fab7fc33d1067804fb455e3dabe5a039 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: fab7fc33d1067804fb455e3dabe5a039 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/View/CreatePointAction.cs b/Editor/2D/ShapeEditor/View/CreatePointAction.cs index 35de9fa..cbd36a8 100644 --- a/Editor/2D/ShapeEditor/View/CreatePointAction.cs +++ b/Editor/2D/ShapeEditor/View/CreatePointAction.cs @@ -1,48 +1,48 @@ -using System; -using UnityEngine; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class CreatePointAction : ClickAction - { - private Control m_PointControl; - - public Func guiToWorld; - public Action onCreatePoint; - public CreatePointAction(Control pointControl, Control edgeControl) : base(edgeControl, 0, false) - { - m_PointControl = pointControl; - } - - protected override void OnTrigger(IGUIState guiState) - { - base.OnTrigger(guiState); - - var index = hoveredControl.layoutData.index; - var position = GetMousePositionWorld(guiState); - - if (onCreatePoint != null) - onCreatePoint(index, position); - - guiState.nearestControl = m_PointControl.ID; - - var data = m_PointControl.layoutData; - data.index = index + 1; - data.position = position; - data.distance = 0f; - - m_PointControl.layoutData = data; - - guiState.changed = true; - } - - private Vector3 GetMousePositionWorld(IGUIState guiState) - { - if (guiToWorld != null) - return guiToWorld(guiState, guiState.mousePosition); - - return guiState.GUIToWorld(guiState.mousePosition, hoveredControl.layoutData.forward, hoveredControl.layoutData.position); - } - } -} +using System; +using UnityEngine; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class CreatePointAction : ClickAction + { + private Control m_PointControl; + + public Func guiToWorld; + public Action onCreatePoint; + public CreatePointAction(Control pointControl, Control edgeControl) : base(edgeControl, 0, false) + { + m_PointControl = pointControl; + } + + protected override void OnTrigger(IGUIState guiState) + { + base.OnTrigger(guiState); + + var index = hoveredControl.layoutData.index; + var position = GetMousePositionWorld(guiState); + + if (onCreatePoint != null) + onCreatePoint(index, position); + + guiState.nearestControl = m_PointControl.ID; + + var data = m_PointControl.layoutData; + data.index = index + 1; + data.position = position; + data.distance = 0f; + + m_PointControl.layoutData = data; + + guiState.changed = true; + } + + private Vector3 GetMousePositionWorld(IGUIState guiState) + { + if (guiToWorld != null) + return guiToWorld(guiState, guiState.mousePosition); + + return guiState.GUIToWorld(guiState.mousePosition, hoveredControl.layoutData.forward, hoveredControl.layoutData.position); + } + } +} diff --git a/Editor/2D/ShapeEditor/View/CreatePointAction.cs.meta b/Editor/2D/ShapeEditor/View/CreatePointAction.cs.meta index 91872cf..f57cf7d 100644 --- a/Editor/2D/ShapeEditor/View/CreatePointAction.cs.meta +++ b/Editor/2D/ShapeEditor/View/CreatePointAction.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 9c6730ad81f0759429631c2258913661 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 9c6730ad81f0759429631c2258913661 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/View/Drawer.cs b/Editor/2D/ShapeEditor/View/Drawer.cs index b00dc91..da6a38d 100644 --- a/Editor/2D/ShapeEditor/View/Drawer.cs +++ b/Editor/2D/ShapeEditor/View/Drawer.cs @@ -1,142 +1,141 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class DefaultStyles - { - public readonly GUIStyle pointNormalStyle; - public readonly GUIStyle pointHoveredStyle; - public readonly GUIStyle pointSelectedStyle; - public readonly GUIStyle pointPreviewStyle; - public readonly GUIStyle pointRemovePreviewStyle; - public readonly GUIStyle tangentNormalStyle; - public readonly GUIStyle tangentHoveredStyle; - public readonly GUIStyle selectionRectStyle; - - public DefaultStyles() - { - var pointNormal = Resources.Load("Path/pointNormal"); - var pointHovered = Resources.Load("Path/pointHovered"); - var pointSelected = Resources.Load("Path/pointSelected"); - var pointPreview = Resources.Load("Path/pointPreview"); - var pointRemovePreview = Resources.Load("Path/pointRemovePreview"); - var tangentNormal = Resources.Load("Path/tangentNormal"); - - pointNormalStyle = CreateStyle(Resources.Load("Path/pointNormal"), Vector2.one * 12f); - pointHoveredStyle = CreateStyle(Resources.Load("Path/pointHovered"), Vector2.one * 12f); - pointSelectedStyle = CreateStyle(Resources.Load("Path/pointSelected"), Vector2.one * 12f); - pointPreviewStyle = CreateStyle(Resources.Load("Path/pointPreview"), Vector2.one * 12f); - pointRemovePreviewStyle = CreateStyle(Resources.Load("Path/pointRemovePreview"), Vector2.one * 12f); - tangentNormalStyle = CreateStyle(Resources.Load("Path/tangentNormal"), Vector2.one * 8f); - tangentHoveredStyle = CreateStyle(Resources.Load("Path/pointHovered"), Vector2.one * 10f); - - selectionRectStyle = GUI.skin.FindStyle("selectionRect"); - } - - private GUIStyle CreateStyle(Texture2D texture, Vector2 size) - { - var guiStyle = new GUIStyle(); - guiStyle.normal.background = texture; - guiStyle.fixedWidth = size.x; - guiStyle.fixedHeight = size.y; - - return guiStyle; - } - } - - internal class Drawer : IDrawer - { - private IGUIState m_GUIState = new GUIState(); - private DefaultStyles m_Styles; - protected DefaultStyles styles - { - get - { - if (m_Styles == null) - m_Styles = new DefaultStyles(); - - return m_Styles; - } - } - - public void DrawSelectionRect(Rect rect) - { - Handles.BeginGUI(); - styles.selectionRectStyle.Draw(rect, GUIContent.none, false, false, false, false); - Handles.EndGUI(); - } - - public void DrawCreatePointPreview(Vector3 position) - { - DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointPreviewStyle); - } - - public void DrawRemovePointPreview(Vector3 position) - { - DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointRemovePreviewStyle); - } - - public void DrawPoint(Vector3 position) - { - DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointNormalStyle); - } - - public void DrawPointHovered(Vector3 position) - { - DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointHoveredStyle); - } - - public void DrawPointSelected(Vector3 position) - { - DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointSelectedStyle); - } - - public void DrawLine(Vector3 p1, Vector3 p2, float width, Color color) - { - Handles.color = color; - Handles.DrawAAPolyLine(width, new Vector3[] { p1, p2 }); - } - - public void DrawDottedLine(Vector3 p1, Vector3 p2, float width, Color color) - { - Handles.color = color; - Handles.DrawDottedLine(p1, p2, width); - } - - public void DrawBezier(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float width, Color color) - { - Handles.color = color; - Handles.DrawBezier(p1, p4, p2, p3, color, null, width); - } - - public void DrawTangent(Vector3 position, Vector3 tangent) - { - DrawLine(position, tangent, 3f, Color.yellow); - DrawGUIStyleCap(0, tangent, Quaternion.identity, m_GUIState.GetHandleSize(tangent), styles.tangentNormalStyle); - } - - - private void DrawGUIStyleCap(int controlID, Vector3 position, Quaternion rotation, float size, GUIStyle guiStyle) - { - if (Camera.current && Vector3.Dot(position - Camera.current.transform.position, Camera.current.transform.forward) < 0f) - return; - - Handles.BeginGUI(); - guiStyle.Draw(GetGUIStyleRect(guiStyle, position), GUIContent.none, controlID); - Handles.EndGUI(); - } - - private Rect GetGUIStyleRect(GUIStyle style, Vector3 position) - { - Vector2 vector = HandleUtility.WorldToGUIPoint(position); - - float fixedWidth = style.fixedWidth; - float fixedHeight = style.fixedHeight; - - return new Rect(vector.x - fixedWidth / 2f, vector.y - fixedHeight / 2f, fixedWidth, fixedHeight); - } - } -} +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class DefaultStyles + { + public readonly GUIStyle pointNormalStyle; + public readonly GUIStyle pointHoveredStyle; + public readonly GUIStyle pointSelectedStyle; + public readonly GUIStyle pointPreviewStyle; + public readonly GUIStyle pointRemovePreviewStyle; + public readonly GUIStyle tangentNormalStyle; + public readonly GUIStyle tangentHoveredStyle; + public readonly GUIStyle selectionRectStyle; + + public DefaultStyles() + { + var pointNormal = Resources.Load("Path/pointNormal"); + var pointHovered = Resources.Load("Path/pointHovered"); + var pointSelected = Resources.Load("Path/pointSelected"); + var pointPreview = Resources.Load("Path/pointPreview"); + var pointRemovePreview = Resources.Load("Path/pointRemovePreview"); + var tangentNormal = Resources.Load("Path/tangentNormal"); + + pointNormalStyle = CreateStyle(Resources.Load("Path/pointNormal"), Vector2.one * 12f); + pointHoveredStyle = CreateStyle(Resources.Load("Path/pointHovered"), Vector2.one * 12f); + pointSelectedStyle = CreateStyle(Resources.Load("Path/pointSelected"), Vector2.one * 12f); + pointPreviewStyle = CreateStyle(Resources.Load("Path/pointPreview"), Vector2.one * 12f); + pointRemovePreviewStyle = CreateStyle(Resources.Load("Path/pointRemovePreview"), Vector2.one * 12f); + tangentNormalStyle = CreateStyle(Resources.Load("Path/tangentNormal"), Vector2.one * 8f); + tangentHoveredStyle = CreateStyle(Resources.Load("Path/pointHovered"), Vector2.one * 10f); + + selectionRectStyle = GUI.skin.FindStyle("selectionRect"); + } + + private GUIStyle CreateStyle(Texture2D texture, Vector2 size) + { + var guiStyle = new GUIStyle(); + guiStyle.normal.background = texture; + guiStyle.fixedWidth = size.x; + guiStyle.fixedHeight = size.y; + + return guiStyle; + } + } + + internal class Drawer : IDrawer + { + private IGUIState m_GUIState = new GUIState(); + private DefaultStyles m_Styles; + protected DefaultStyles styles + { + get + { + if (m_Styles == null) + m_Styles = new DefaultStyles(); + + return m_Styles; + } + } + + public void DrawSelectionRect(Rect rect) + { + Handles.BeginGUI(); + styles.selectionRectStyle.Draw(rect, GUIContent.none, false, false, false, false); + Handles.EndGUI(); + } + + public void DrawCreatePointPreview(Vector3 position) + { + DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointPreviewStyle); + } + + public void DrawRemovePointPreview(Vector3 position) + { + DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointRemovePreviewStyle); + } + + public void DrawPoint(Vector3 position) + { + DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointNormalStyle); + } + + public void DrawPointHovered(Vector3 position) + { + DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointHoveredStyle); + } + + public void DrawPointSelected(Vector3 position) + { + DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointSelectedStyle); + } + + public void DrawLine(Vector3 p1, Vector3 p2, float width, Color color) + { + Handles.color = color; + Handles.DrawAAPolyLine(width, new Vector3[] { p1, p2 }); + } + + public void DrawDottedLine(Vector3 p1, Vector3 p2, float width, Color color) + { + Handles.color = color; + Handles.DrawDottedLine(p1, p2, width); + } + + public void DrawBezier(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float width, Color color) + { + Handles.color = color; + Handles.DrawBezier(p1, p4, p2, p3, color, null, width); + } + + public void DrawTangent(Vector3 position, Vector3 tangent) + { + DrawLine(position, tangent, 3f, Color.yellow); + DrawGUIStyleCap(0, tangent, Quaternion.identity, m_GUIState.GetHandleSize(tangent), styles.tangentNormalStyle); + } + + private void DrawGUIStyleCap(int controlID, Vector3 position, Quaternion rotation, float size, GUIStyle guiStyle) + { + if (Camera.current && Vector3.Dot(position - Camera.current.transform.position, Camera.current.transform.forward) < 0f) + return; + + Handles.BeginGUI(); + guiStyle.Draw(GetGUIStyleRect(guiStyle, position), GUIContent.none, controlID); + Handles.EndGUI(); + } + + private Rect GetGUIStyleRect(GUIStyle style, Vector3 position) + { + Vector2 vector = HandleUtility.WorldToGUIPoint(position); + + float fixedWidth = style.fixedWidth; + float fixedHeight = style.fixedHeight; + + return new Rect(vector.x - fixedWidth / 2f, vector.y - fixedHeight / 2f, fixedWidth, fixedHeight); + } + } +} diff --git a/Editor/2D/ShapeEditor/View/Drawer.cs.meta b/Editor/2D/ShapeEditor/View/Drawer.cs.meta index 2d72edc..4216e47 100644 --- a/Editor/2D/ShapeEditor/View/Drawer.cs.meta +++ b/Editor/2D/ShapeEditor/View/Drawer.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: dc769d693640b604786cee87281a2574 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: dc769d693640b604786cee87281a2574 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/View/EditablePathView.cs b/Editor/2D/ShapeEditor/View/EditablePathView.cs index c21f880..8155d2a 100644 --- a/Editor/2D/ShapeEditor/View/EditablePathView.cs +++ b/Editor/2D/ShapeEditor/View/EditablePathView.cs @@ -1,490 +1,489 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal class EditablePathView : IEditablePathView - { - const float kSnappingDistance = 15f; - const string kDeleteCommandName = "Delete"; - const string kSoftDeleteCommandName = "SoftDelete"; - public IEditablePathController controller { get; set; } - private Control m_PointControl; - private Control m_EdgeControl; - private Control m_LeftTangentControl; - private Control m_RightTangentControl; - private GUIAction m_MovePointAction; - private GUIAction m_MoveEdgeAction; - private GUIAction m_CreatePointAction; - private GUIAction m_RemovePointAction1; - private GUIAction m_RemovePointAction2; - private GUIAction m_MoveLeftTangentAction; - private GUIAction m_MoveRightTangentAction; - private IDrawer m_Drawer; - - public EditablePathView() : this(new Drawer()) { } - - public EditablePathView(IDrawer drawer) - { - m_Drawer = drawer; - - m_PointControl = new GenericControl("Point") - { - count = GetPointCount, - distance = (guiState, i) => - { - var position = GetPoint(i).position; - return guiState.DistanceToCircle(position, guiState.GetHandleSize(position) * 10f); - }, - position = (i) => { return GetPoint(i).position; }, - forward = (i) => { return GetForward(); }, - up = (i) => { return GetUp(); }, - right = (i) => { return GetRight(); }, - onRepaint = DrawPoint - }; - - m_EdgeControl = new GenericControl("Edge") - { - onEndLayout = (guiState) => { controller.AddClosestPath(m_EdgeControl.layoutData.distance); }, - count = GetEdgeCount, - distance = DistanceToEdge, - position = (i) => { return GetPoint(i).position; }, - forward = (i) => { return GetForward(); }, - up = (i) => { return GetUp(); }, - right = (i) => { return GetRight(); }, - onRepaint = DrawEdge - }; - - m_LeftTangentControl = new GenericControl("LeftTangent") - { - count = () => - { - if (GetShapeType() != ShapeType.Spline) - return 0; - - return GetPointCount(); - }, - distance = (guiState, i) => - { - if (!IsSelected(i) || IsOpenEnded() && i == 0) - return float.MaxValue; - - var position = GetLeftTangent(i); - return guiState.DistanceToCircle(position, guiState.GetHandleSize(position) * 10f); - }, - position = (i) => { return GetLeftTangent(i); }, - forward = (i) => { return GetForward(); }, - up = (i) => { return GetUp(); }, - right = (i) => { return GetRight(); }, - onRepaint = (guiState, control, i) => - { - if (!IsSelected(i) || IsOpenEnded() && i == 0) - return; - - var position = GetPoint(i).position; - var leftTangent = GetLeftTangent(i); - - m_Drawer.DrawTangent(position, leftTangent); - } - }; - - m_RightTangentControl = new GenericControl("RightTangent") - { - count = () => - { - if (GetShapeType() != ShapeType.Spline) - return 0; - - return GetPointCount(); - }, - distance = (guiState, i) => - { - if (!IsSelected(i) || IsOpenEnded() && i == GetPointCount()-1) - return float.MaxValue; - - var position = GetRightTangent(i); - return guiState.DistanceToCircle(position, guiState.GetHandleSize(position) * 10f); - }, - position = (i) => { return GetRightTangent(i); }, - forward = (i) => { return GetForward(); }, - up = (i) => { return GetUp(); }, - right = (i) => { return GetRight(); }, - onRepaint = (guiState, control, i) => - { - if (!IsSelected(i) || IsOpenEnded() && i == GetPointCount()-1) - return; - - var position = GetPoint(i).position; - var rightTangent = GetRightTangent(i); - - m_Drawer.DrawTangent(position, rightTangent); - } - }; - - m_CreatePointAction = new CreatePointAction(m_PointControl, m_EdgeControl) - { - enable = (guiState, action) => { return !guiState.isShiftDown && controller.closestEditablePath == controller.editablePath; }, - enableRepaint = EnableCreatePointRepaint, - repaintOnMouseMove = (guiState, action) => { return true; }, - guiToWorld = GUIToWorld, - onCreatePoint = (index, position) => - { - controller.RegisterUndo("Create Point"); - controller.CreatePoint(index, position); - }, - onPreRepaint = (guiState, action) => - { - if (GetPointCount() > 0) - { - var position = ClosestPointInEdge(guiState, guiState.mousePosition, m_EdgeControl.layoutData.index); - m_Drawer.DrawCreatePointPreview(position); - } - } - }; - - Action removePoints = (guiState) => - { - controller.RegisterUndo("Remove Point"); - controller.RemoveSelectedPoints(); - guiState.changed = true; - }; - - m_RemovePointAction1 = new CommandAction(kDeleteCommandName) - { - enable = (guiState, action) => { return GetSelectedPointCount() > 0; }, - onCommand = removePoints - }; - - m_RemovePointAction2 = new CommandAction(kSoftDeleteCommandName) - { - enable = (guiState, action) => { return GetSelectedPointCount() > 0; }, - onCommand = removePoints - }; - - m_MovePointAction = new SliderAction(m_PointControl) - { - onClick = (guiState, control) => - { - var index = control.layoutData.index; - - if (!guiState.isActionKeyDown && !IsSelected(index)) - controller.ClearSelection(); - - controller.SelectPoint(index, true); - guiState.changed = true; - }, - onSliderBegin = (guiState, control, position) => - { - controller.RegisterUndo("Move Point"); - }, - onSliderChanged = (guiState, control, position) => - { - var index = control.hotLayoutData.index; - var delta = SnapIfNeeded(position) - GetPoint(index).position; - - controller.MoveSelectedPoints(delta); - } - }; - - m_MoveEdgeAction = new SliderAction(m_EdgeControl) - { - enable = (guiState, action) => { return guiState.isShiftDown; }, - onSliderBegin = (guiState, control, position) => - { - controller.RegisterUndo("Move Edge"); - }, - onSliderChanged = (guiState, control, position) => - { - var index = control.hotLayoutData.index; - var delta = position - GetPoint(index).position; - - controller.MoveEdge(index, delta); - } - }; - - var cachedRightTangent = Vector3.zero; - var cachedLeftTangent = Vector3.zero; - - m_MoveLeftTangentAction = new SliderAction(m_LeftTangentControl) - { - onSliderBegin = (guiState, control, position) => - { - controller.RegisterUndo("Move Tangent"); - cachedRightTangent = GetPoint(control.hotLayoutData.index).rightTangent; - }, - onSliderChanged = (guiState, control, position) => - { - var index = control.hotLayoutData.index; - var setToLinear = guiState.nearestControl == m_PointControl.ID && m_PointControl.layoutData.index == index; - - controller.SetLeftTangent(index, position, setToLinear, guiState.isShiftDown, cachedRightTangent); - - }, - onSliderEnd = (guiState, control, position) => - { - controller.editablePath.UpdateTangentMode(control.hotLayoutData.index); - guiState.changed = true; - } - }; - - m_MoveRightTangentAction = new SliderAction(m_RightTangentControl) - { - onSliderBegin = (guiState, control, position) => - { - controller.RegisterUndo("Move Tangent"); - cachedLeftTangent = GetPoint(control.hotLayoutData.index).leftTangent; - }, - onSliderChanged = (guiState, control, position) => - { - var index = control.hotLayoutData.index; - var setToLinear = guiState.nearestControl == m_PointControl.ID && m_PointControl.layoutData.index == index; - - controller.SetRightTangent(index, position, setToLinear, guiState.isShiftDown, cachedLeftTangent); - }, - onSliderEnd = (guiState, control, position) => - { - controller.editablePath.UpdateTangentMode(control.hotLayoutData.index); - guiState.changed = true; - } - }; - } - - public void Install(GUISystem guiSystem) - { - guiSystem.AddControl(m_EdgeControl); - guiSystem.AddControl(m_PointControl); - guiSystem.AddControl(m_LeftTangentControl); - guiSystem.AddControl(m_RightTangentControl); - guiSystem.AddAction(m_CreatePointAction); - guiSystem.AddAction(m_RemovePointAction1); - guiSystem.AddAction(m_RemovePointAction2); - guiSystem.AddAction(m_MovePointAction); - guiSystem.AddAction(m_MoveEdgeAction); - guiSystem.AddAction(m_MoveLeftTangentAction); - guiSystem.AddAction(m_MoveRightTangentAction); - } - - public void Uninstall(GUISystem guiSystem) - { - guiSystem.RemoveControl(m_EdgeControl); - guiSystem.RemoveControl(m_PointControl); - guiSystem.RemoveControl(m_LeftTangentControl); - guiSystem.RemoveControl(m_RightTangentControl); - guiSystem.RemoveAction(m_CreatePointAction); - guiSystem.RemoveAction(m_RemovePointAction1); - guiSystem.RemoveAction(m_RemovePointAction2); - guiSystem.RemoveAction(m_MovePointAction); - guiSystem.RemoveAction(m_MoveEdgeAction); - guiSystem.RemoveAction(m_MoveLeftTangentAction); - guiSystem.RemoveAction(m_MoveRightTangentAction); - } - - private ControlPoint GetPoint(int index) - { - return controller.editablePath.GetPoint(index); - } - - private int GetPointCount() - { - return controller.editablePath.pointCount; - } - - private int GetEdgeCount() - { - if (controller.editablePath.isOpenEnded) - return controller.editablePath.pointCount - 1; - - return controller.editablePath.pointCount; - } - - private int GetSelectedPointCount() - { - return controller.editablePath.selection.Count; - } - - private bool IsSelected(int index) - { - return controller.editablePath.selection.Contains(index); - } - - private Vector3 GetForward() - { - return controller.editablePath.forward; - } - - private Vector3 GetUp() - { - return controller.editablePath.up; - } - - private Vector3 GetRight() - { - return controller.editablePath.right; - } - - private Matrix4x4 GetLocalToWorldMatrix() - { - return controller.editablePath.localToWorldMatrix; - } - - private ShapeType GetShapeType() - { - return controller.editablePath.shapeType; - } - - private bool IsOpenEnded() - { - return controller.editablePath.isOpenEnded; - } - - private Vector3 GetLeftTangent(int index) - { - return controller.editablePath.CalculateLeftTangent(index); - } - - private Vector3 GetRightTangent(int index) - { - return controller.editablePath.CalculateRightTangent(index); - } - - private int NextIndex(int index) - { - return EditablePathUtility.Mod(index + 1, GetPointCount()); - } - - private ControlPoint NextControlPoint(int index) - { - return GetPoint(NextIndex(index)); - } - - private int PrevIndex(int index) - { - return EditablePathUtility.Mod(index - 1, GetPointCount()); - } - - private ControlPoint PrevControlPoint(int index) - { - return GetPoint(PrevIndex(index)); - } - - private Vector3 ClosestPointInEdge(IGUIState guiState, Vector2 mousePosition, int index) - { - if (GetShapeType() == ShapeType.Polygon) - { - var p0 = GetPoint(index).position; - var p1 = NextControlPoint(index).position; - var mouseWorldPosition = GUIToWorld(guiState, mousePosition); - - var dir1 = (mouseWorldPosition - p0); - var dir2 = (p1 - p0); - - return Mathf.Clamp01(Vector3.Dot(dir1, dir2.normalized) / dir2.magnitude) * dir2 + p0; - } - else if (GetShapeType() == ShapeType.Spline) - { - var nextIndex = NextIndex(index); - float t; - return BezierUtility.ClosestPointOnCurve( - GUIToWorld(guiState, mousePosition), - GetPoint(index).position, - GetPoint(nextIndex).position, - GetRightTangent(index), - GetLeftTangent(nextIndex), - out t); - } - - return Vector3.zero; - } - - private float DistanceToEdge(IGUIState guiState, int index) - { - if (GetShapeType() == ShapeType.Polygon) - { - return guiState.DistanceToSegment(GetPoint(index).position, NextControlPoint(index).position); - } - else if (GetShapeType() == ShapeType.Spline) - { - var closestPoint = ClosestPointInEdge(guiState, guiState.mousePosition, index); - var closestPoint2 = HandleUtility.WorldToGUIPoint(closestPoint); - - return (closestPoint2 - guiState.mousePosition).magnitude; - } - - return float.MaxValue; - } - - private Vector3 GUIToWorld(IGUIState guiState, Vector2 position) - { - return guiState.GUIToWorld(position, GetForward(), GetLocalToWorldMatrix().MultiplyPoint3x4(Vector3.zero)); - } - - private void DrawPoint(IGUIState guiState, Control control, int index) - { - var position = GetPoint(index).position; - - if (guiState.hotControl == control.actionID && control.hotLayoutData.index == index || IsSelected(index)) - m_Drawer.DrawPointSelected(position); - else if (guiState.hotControl == 0 && guiState.nearestControl == control.ID && control.layoutData.index == index) - m_Drawer.DrawPointHovered(position); - else - m_Drawer.DrawPoint(position); - } - - private void DrawEdge(IGUIState guiState, Control control, int index) - { - if (GetShapeType() == ShapeType.Polygon) - { - var nextIndex = NextIndex(index); - var color = Color.white; - - if(guiState.nearestControl == control.ID && control.layoutData.index == index && guiState.hotControl == 0) - color = Color.yellow; - - m_Drawer.DrawLine(GetPoint(index).position, GetPoint(nextIndex).position, 5f, color); - } - else if (GetShapeType() == ShapeType.Spline) - { - var nextIndex = NextIndex(index); - var color = Color.white; - - if(guiState.nearestControl == control.ID && control.layoutData.index == index && guiState.hotControl == 0) - color = Color.yellow; - - m_Drawer.DrawBezier( - GetPoint(index).position, - GetRightTangent(index), - GetLeftTangent(nextIndex), - GetPoint(nextIndex).position, - 5f, - color); - } - } - - private bool EnableCreatePointRepaint(IGUIState guiState, GUIAction action) - { - return guiState.nearestControl != m_PointControl.ID && - guiState.hotControl == 0 && - (guiState.nearestControl != m_LeftTangentControl.ID) && - (guiState.nearestControl != m_RightTangentControl.ID); - } - - private Vector3 SnapIfNeeded(Vector3 position) - { - if (!controller.enableSnapping || controller.snapping == null) - return position; - - var guiPosition = HandleUtility.WorldToGUIPoint(position); - var snappedGuiPosition = HandleUtility.WorldToGUIPoint(controller.snapping.Snap(position)); - var sqrDistance = (guiPosition - snappedGuiPosition).sqrMagnitude; - - if (sqrDistance < kSnappingDistance * kSnappingDistance) - position = controller.snapping.Snap(position); - - return position; - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal class EditablePathView : IEditablePathView + { + const float kSnappingDistance = 15f; + const string kDeleteCommandName = "Delete"; + const string kSoftDeleteCommandName = "SoftDelete"; + public IEditablePathController controller { get; set; } + private Control m_PointControl; + private Control m_EdgeControl; + private Control m_LeftTangentControl; + private Control m_RightTangentControl; + private GUIAction m_MovePointAction; + private GUIAction m_MoveEdgeAction; + private GUIAction m_CreatePointAction; + private GUIAction m_RemovePointAction1; + private GUIAction m_RemovePointAction2; + private GUIAction m_MoveLeftTangentAction; + private GUIAction m_MoveRightTangentAction; + private IDrawer m_Drawer; + + public EditablePathView() : this(new Drawer()) { } + + public EditablePathView(IDrawer drawer) + { + m_Drawer = drawer; + + m_PointControl = new GenericControl("Point") + { + count = GetPointCount, + distance = (guiState, i) => + { + var position = GetPoint(i).position; + return guiState.DistanceToCircle(position, guiState.GetHandleSize(position) * 10f); + }, + position = (i) => { return GetPoint(i).position; }, + forward = (i) => { return GetForward(); }, + up = (i) => { return GetUp(); }, + right = (i) => { return GetRight(); }, + onRepaint = DrawPoint + }; + + m_EdgeControl = new GenericControl("Edge") + { + onEndLayout = (guiState) => { controller.AddClosestPath(m_EdgeControl.layoutData.distance); }, + count = GetEdgeCount, + distance = DistanceToEdge, + position = (i) => { return GetPoint(i).position; }, + forward = (i) => { return GetForward(); }, + up = (i) => { return GetUp(); }, + right = (i) => { return GetRight(); }, + onRepaint = DrawEdge + }; + + m_LeftTangentControl = new GenericControl("LeftTangent") + { + count = () => + { + if (GetShapeType() != ShapeType.Spline) + return 0; + + return GetPointCount(); + }, + distance = (guiState, i) => + { + if (!IsSelected(i) || IsOpenEnded() && i == 0) + return float.MaxValue; + + var position = GetLeftTangent(i); + return guiState.DistanceToCircle(position, guiState.GetHandleSize(position) * 10f); + }, + position = (i) => { return GetLeftTangent(i); }, + forward = (i) => { return GetForward(); }, + up = (i) => { return GetUp(); }, + right = (i) => { return GetRight(); }, + onRepaint = (guiState, control, i) => + { + if (!IsSelected(i) || IsOpenEnded() && i == 0) + return; + + var position = GetPoint(i).position; + var leftTangent = GetLeftTangent(i); + + m_Drawer.DrawTangent(position, leftTangent); + } + }; + + m_RightTangentControl = new GenericControl("RightTangent") + { + count = () => + { + if (GetShapeType() != ShapeType.Spline) + return 0; + + return GetPointCount(); + }, + distance = (guiState, i) => + { + if (!IsSelected(i) || IsOpenEnded() && i == GetPointCount() - 1) + return float.MaxValue; + + var position = GetRightTangent(i); + return guiState.DistanceToCircle(position, guiState.GetHandleSize(position) * 10f); + }, + position = (i) => { return GetRightTangent(i); }, + forward = (i) => { return GetForward(); }, + up = (i) => { return GetUp(); }, + right = (i) => { return GetRight(); }, + onRepaint = (guiState, control, i) => + { + if (!IsSelected(i) || IsOpenEnded() && i == GetPointCount() - 1) + return; + + var position = GetPoint(i).position; + var rightTangent = GetRightTangent(i); + + m_Drawer.DrawTangent(position, rightTangent); + } + }; + + m_CreatePointAction = new CreatePointAction(m_PointControl, m_EdgeControl) + { + enable = (guiState, action) => { return !guiState.isShiftDown && controller.closestEditablePath == controller.editablePath; }, + enableRepaint = EnableCreatePointRepaint, + repaintOnMouseMove = (guiState, action) => { return true; }, + guiToWorld = GUIToWorld, + onCreatePoint = (index, position) => + { + controller.RegisterUndo("Create Point"); + controller.CreatePoint(index, position); + }, + onPreRepaint = (guiState, action) => + { + if (GetPointCount() > 0) + { + var position = ClosestPointInEdge(guiState, guiState.mousePosition, m_EdgeControl.layoutData.index); + m_Drawer.DrawCreatePointPreview(position); + } + } + }; + + Action removePoints = (guiState) => + { + controller.RegisterUndo("Remove Point"); + controller.RemoveSelectedPoints(); + guiState.changed = true; + }; + + m_RemovePointAction1 = new CommandAction(kDeleteCommandName) + { + enable = (guiState, action) => { return GetSelectedPointCount() > 0; }, + onCommand = removePoints + }; + + m_RemovePointAction2 = new CommandAction(kSoftDeleteCommandName) + { + enable = (guiState, action) => { return GetSelectedPointCount() > 0; }, + onCommand = removePoints + }; + + m_MovePointAction = new SliderAction(m_PointControl) + { + onClick = (guiState, control) => + { + var index = control.layoutData.index; + + if (!guiState.isActionKeyDown && !IsSelected(index)) + controller.ClearSelection(); + + controller.SelectPoint(index, true); + guiState.changed = true; + }, + onSliderBegin = (guiState, control, position) => + { + controller.RegisterUndo("Move Point"); + }, + onSliderChanged = (guiState, control, position) => + { + var index = control.hotLayoutData.index; + var delta = SnapIfNeeded(position) - GetPoint(index).position; + + controller.MoveSelectedPoints(delta); + } + }; + + m_MoveEdgeAction = new SliderAction(m_EdgeControl) + { + enable = (guiState, action) => { return guiState.isShiftDown; }, + onSliderBegin = (guiState, control, position) => + { + controller.RegisterUndo("Move Edge"); + }, + onSliderChanged = (guiState, control, position) => + { + var index = control.hotLayoutData.index; + var delta = position - GetPoint(index).position; + + controller.MoveEdge(index, delta); + } + }; + + var cachedRightTangent = Vector3.zero; + var cachedLeftTangent = Vector3.zero; + + m_MoveLeftTangentAction = new SliderAction(m_LeftTangentControl) + { + onSliderBegin = (guiState, control, position) => + { + controller.RegisterUndo("Move Tangent"); + cachedRightTangent = GetPoint(control.hotLayoutData.index).rightTangent; + }, + onSliderChanged = (guiState, control, position) => + { + var index = control.hotLayoutData.index; + var setToLinear = guiState.nearestControl == m_PointControl.ID && m_PointControl.layoutData.index == index; + + controller.SetLeftTangent(index, position, setToLinear, guiState.isShiftDown, cachedRightTangent); + }, + onSliderEnd = (guiState, control, position) => + { + controller.editablePath.UpdateTangentMode(control.hotLayoutData.index); + guiState.changed = true; + } + }; + + m_MoveRightTangentAction = new SliderAction(m_RightTangentControl) + { + onSliderBegin = (guiState, control, position) => + { + controller.RegisterUndo("Move Tangent"); + cachedLeftTangent = GetPoint(control.hotLayoutData.index).leftTangent; + }, + onSliderChanged = (guiState, control, position) => + { + var index = control.hotLayoutData.index; + var setToLinear = guiState.nearestControl == m_PointControl.ID && m_PointControl.layoutData.index == index; + + controller.SetRightTangent(index, position, setToLinear, guiState.isShiftDown, cachedLeftTangent); + }, + onSliderEnd = (guiState, control, position) => + { + controller.editablePath.UpdateTangentMode(control.hotLayoutData.index); + guiState.changed = true; + } + }; + } + + public void Install(GUISystem guiSystem) + { + guiSystem.AddControl(m_EdgeControl); + guiSystem.AddControl(m_PointControl); + guiSystem.AddControl(m_LeftTangentControl); + guiSystem.AddControl(m_RightTangentControl); + guiSystem.AddAction(m_CreatePointAction); + guiSystem.AddAction(m_RemovePointAction1); + guiSystem.AddAction(m_RemovePointAction2); + guiSystem.AddAction(m_MovePointAction); + guiSystem.AddAction(m_MoveEdgeAction); + guiSystem.AddAction(m_MoveLeftTangentAction); + guiSystem.AddAction(m_MoveRightTangentAction); + } + + public void Uninstall(GUISystem guiSystem) + { + guiSystem.RemoveControl(m_EdgeControl); + guiSystem.RemoveControl(m_PointControl); + guiSystem.RemoveControl(m_LeftTangentControl); + guiSystem.RemoveControl(m_RightTangentControl); + guiSystem.RemoveAction(m_CreatePointAction); + guiSystem.RemoveAction(m_RemovePointAction1); + guiSystem.RemoveAction(m_RemovePointAction2); + guiSystem.RemoveAction(m_MovePointAction); + guiSystem.RemoveAction(m_MoveEdgeAction); + guiSystem.RemoveAction(m_MoveLeftTangentAction); + guiSystem.RemoveAction(m_MoveRightTangentAction); + } + + private ControlPoint GetPoint(int index) + { + return controller.editablePath.GetPoint(index); + } + + private int GetPointCount() + { + return controller.editablePath.pointCount; + } + + private int GetEdgeCount() + { + if (controller.editablePath.isOpenEnded) + return controller.editablePath.pointCount - 1; + + return controller.editablePath.pointCount; + } + + private int GetSelectedPointCount() + { + return controller.editablePath.selection.Count; + } + + private bool IsSelected(int index) + { + return controller.editablePath.selection.Contains(index); + } + + private Vector3 GetForward() + { + return controller.editablePath.forward; + } + + private Vector3 GetUp() + { + return controller.editablePath.up; + } + + private Vector3 GetRight() + { + return controller.editablePath.right; + } + + private Matrix4x4 GetLocalToWorldMatrix() + { + return controller.editablePath.localToWorldMatrix; + } + + private ShapeType GetShapeType() + { + return controller.editablePath.shapeType; + } + + private bool IsOpenEnded() + { + return controller.editablePath.isOpenEnded; + } + + private Vector3 GetLeftTangent(int index) + { + return controller.editablePath.CalculateLeftTangent(index); + } + + private Vector3 GetRightTangent(int index) + { + return controller.editablePath.CalculateRightTangent(index); + } + + private int NextIndex(int index) + { + return EditablePathUtility.Mod(index + 1, GetPointCount()); + } + + private ControlPoint NextControlPoint(int index) + { + return GetPoint(NextIndex(index)); + } + + private int PrevIndex(int index) + { + return EditablePathUtility.Mod(index - 1, GetPointCount()); + } + + private ControlPoint PrevControlPoint(int index) + { + return GetPoint(PrevIndex(index)); + } + + private Vector3 ClosestPointInEdge(IGUIState guiState, Vector2 mousePosition, int index) + { + if (GetShapeType() == ShapeType.Polygon) + { + var p0 = GetPoint(index).position; + var p1 = NextControlPoint(index).position; + var mouseWorldPosition = GUIToWorld(guiState, mousePosition); + + var dir1 = (mouseWorldPosition - p0); + var dir2 = (p1 - p0); + + return Mathf.Clamp01(Vector3.Dot(dir1, dir2.normalized) / dir2.magnitude) * dir2 + p0; + } + else if (GetShapeType() == ShapeType.Spline) + { + var nextIndex = NextIndex(index); + float t; + return BezierUtility.ClosestPointOnCurve( + GUIToWorld(guiState, mousePosition), + GetPoint(index).position, + GetPoint(nextIndex).position, + GetRightTangent(index), + GetLeftTangent(nextIndex), + out t); + } + + return Vector3.zero; + } + + private float DistanceToEdge(IGUIState guiState, int index) + { + if (GetShapeType() == ShapeType.Polygon) + { + return guiState.DistanceToSegment(GetPoint(index).position, NextControlPoint(index).position); + } + else if (GetShapeType() == ShapeType.Spline) + { + var closestPoint = ClosestPointInEdge(guiState, guiState.mousePosition, index); + var closestPoint2 = HandleUtility.WorldToGUIPoint(closestPoint); + + return (closestPoint2 - guiState.mousePosition).magnitude; + } + + return float.MaxValue; + } + + private Vector3 GUIToWorld(IGUIState guiState, Vector2 position) + { + return guiState.GUIToWorld(position, GetForward(), GetLocalToWorldMatrix().MultiplyPoint3x4(Vector3.zero)); + } + + private void DrawPoint(IGUIState guiState, Control control, int index) + { + var position = GetPoint(index).position; + + if (guiState.hotControl == control.actionID && control.hotLayoutData.index == index || IsSelected(index)) + m_Drawer.DrawPointSelected(position); + else if (guiState.hotControl == 0 && guiState.nearestControl == control.ID && control.layoutData.index == index) + m_Drawer.DrawPointHovered(position); + else + m_Drawer.DrawPoint(position); + } + + private void DrawEdge(IGUIState guiState, Control control, int index) + { + if (GetShapeType() == ShapeType.Polygon) + { + var nextIndex = NextIndex(index); + var color = Color.white; + + if (guiState.nearestControl == control.ID && control.layoutData.index == index && guiState.hotControl == 0) + color = Color.yellow; + + m_Drawer.DrawLine(GetPoint(index).position, GetPoint(nextIndex).position, 5f, color); + } + else if (GetShapeType() == ShapeType.Spline) + { + var nextIndex = NextIndex(index); + var color = Color.white; + + if (guiState.nearestControl == control.ID && control.layoutData.index == index && guiState.hotControl == 0) + color = Color.yellow; + + m_Drawer.DrawBezier( + GetPoint(index).position, + GetRightTangent(index), + GetLeftTangent(nextIndex), + GetPoint(nextIndex).position, + 5f, + color); + } + } + + private bool EnableCreatePointRepaint(IGUIState guiState, GUIAction action) + { + return guiState.nearestControl != m_PointControl.ID && + guiState.hotControl == 0 && + (guiState.nearestControl != m_LeftTangentControl.ID) && + (guiState.nearestControl != m_RightTangentControl.ID); + } + + private Vector3 SnapIfNeeded(Vector3 position) + { + if (!controller.enableSnapping || controller.snapping == null) + return position; + + var guiPosition = HandleUtility.WorldToGUIPoint(position); + var snappedGuiPosition = HandleUtility.WorldToGUIPoint(controller.snapping.Snap(position)); + var sqrDistance = (guiPosition - snappedGuiPosition).sqrMagnitude; + + if (sqrDistance < kSnappingDistance * kSnappingDistance) + position = controller.snapping.Snap(position); + + return position; + } + } +} diff --git a/Editor/2D/ShapeEditor/View/EditablePathView.cs.meta b/Editor/2D/ShapeEditor/View/EditablePathView.cs.meta index fb289bd..15586ae 100644 --- a/Editor/2D/ShapeEditor/View/EditablePathView.cs.meta +++ b/Editor/2D/ShapeEditor/View/EditablePathView.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 43aa2fe64040d514db3eae829bc00015 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 43aa2fe64040d514db3eae829bc00015 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/View/IDrawer.cs b/Editor/2D/ShapeEditor/View/IDrawer.cs index 7d30789..58808f9 100644 --- a/Editor/2D/ShapeEditor/View/IDrawer.cs +++ b/Editor/2D/ShapeEditor/View/IDrawer.cs @@ -1,18 +1,18 @@ -using UnityEngine; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface IDrawer - { - void DrawSelectionRect(Rect rect); - void DrawCreatePointPreview(Vector3 position); - void DrawRemovePointPreview(Vector3 position); - void DrawPoint(Vector3 position); - void DrawPointHovered(Vector3 position); - void DrawPointSelected(Vector3 position); - void DrawLine(Vector3 p1, Vector3 p2, float width, Color color); - void DrawDottedLine(Vector3 p1, Vector3 p2, float width, Color color); - void DrawBezier(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float width, Color color); - void DrawTangent(Vector3 position, Vector3 tangent); - } -} +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface IDrawer + { + void DrawSelectionRect(Rect rect); + void DrawCreatePointPreview(Vector3 position); + void DrawRemovePointPreview(Vector3 position); + void DrawPoint(Vector3 position); + void DrawPointHovered(Vector3 position); + void DrawPointSelected(Vector3 position); + void DrawLine(Vector3 p1, Vector3 p2, float width, Color color); + void DrawDottedLine(Vector3 p1, Vector3 p2, float width, Color color); + void DrawBezier(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float width, Color color); + void DrawTangent(Vector3 position, Vector3 tangent); + } +} diff --git a/Editor/2D/ShapeEditor/View/IDrawer.cs.meta b/Editor/2D/ShapeEditor/View/IDrawer.cs.meta index 92d0381..7c8b92a 100644 --- a/Editor/2D/ShapeEditor/View/IDrawer.cs.meta +++ b/Editor/2D/ShapeEditor/View/IDrawer.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: e4f945cd340f9494cb84ebb7bb27c40e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e4f945cd340f9494cb84ebb7bb27c40e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/ShapeEditor/View/IEditablePathView.cs b/Editor/2D/ShapeEditor/View/IEditablePathView.cs index 3eac2d6..7ef7b8c 100644 --- a/Editor/2D/ShapeEditor/View/IEditablePathView.cs +++ b/Editor/2D/ShapeEditor/View/IEditablePathView.cs @@ -1,13 +1,13 @@ -using System; -using UnityEngine; -using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; - -namespace UnityEditor.Experimental.Rendering.Universal.Path2D -{ - internal interface IEditablePathView - { - IEditablePathController controller { get; set; } - void Install(GUISystem guiSystem); - void Uninstall(GUISystem guiSystem); - } -} +using System; +using UnityEngine; +using UnityEditor.Rendering.Universal.Path2D.GUIFramework; + +namespace UnityEditor.Rendering.Universal.Path2D +{ + internal interface IEditablePathView + { + IEditablePathController controller { get; set; } + void Install(GUISystem guiSystem); + void Uninstall(GUISystem guiSystem); + } +} diff --git a/Editor/2D/ShapeEditor/View/IEditablePathView.cs.meta b/Editor/2D/ShapeEditor/View/IEditablePathView.cs.meta index 5c68a89..ea09e19 100644 --- a/Editor/2D/ShapeEditor/View/IEditablePathView.cs.meta +++ b/Editor/2D/ShapeEditor/View/IEditablePathView.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 3bdf894aee4a5d64d9f1b05dfa56fa34 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 3bdf894aee4a5d64d9f1b05dfa56fa34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/2D/SortingLayerDropDown.cs b/Editor/2D/SortingLayerDropDown.cs index 8f99bf7..625f766 100644 --- a/Editor/2D/SortingLayerDropDown.cs +++ b/Editor/2D/SortingLayerDropDown.cs @@ -1,149 +1,148 @@ -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEngine.Experimental.Rendering.Universal; - -namespace UnityEditor.Experimental.Rendering.Universal -{ - internal class SortingLayerDropDown - { - private class LayerSelectionData - { - public SerializedObject serializedObject; - public Object[] targets; - public int layerID; - public System.Action onSelectionChanged; - - public LayerSelectionData(SerializedObject so, int lid, Object[] tgts, System.Action selectionChangedCallback) - { - serializedObject = so; - layerID = lid; - targets = tgts; - onSelectionChanged = selectionChangedCallback; - } - } - - private static class Styles - { - public static GUIContent sortingLayerAll = EditorGUIUtility.TrTextContent("All"); - public static GUIContent sortingLayerNone = EditorGUIUtility.TrTextContent("None"); - public static GUIContent sortingLayerMixed = EditorGUIUtility.TrTextContent("Mixed..."); - } - - SortingLayer[] m_AllSortingLayers; - GUIContent[] m_AllSortingLayerNames; - List m_ApplyToSortingLayersList; - SerializedProperty m_ApplyToSortingLayers; - - public void OnEnable(SerializedObject serializedObject, string propertyName) - { - m_ApplyToSortingLayers = serializedObject.FindProperty(propertyName); - m_ApplyToSortingLayersList = new List(m_ApplyToSortingLayers.arraySize); - - m_AllSortingLayers = SortingLayer.layers; - m_AllSortingLayerNames = m_AllSortingLayers.Select(x => new GUIContent(x.name)).ToArray(); - } - - void UpdateApplyToSortingLayersArray(object layerSelectionDataObject) - { - LayerSelectionData layerSelectionData = (LayerSelectionData)layerSelectionDataObject; - - m_ApplyToSortingLayers.ClearArray(); - for (int i = 0; i < m_ApplyToSortingLayersList.Count; ++i) - { - m_ApplyToSortingLayers.InsertArrayElementAtIndex(i); - m_ApplyToSortingLayers.GetArrayElementAtIndex(i).intValue = m_ApplyToSortingLayersList[i]; - } - - if (layerSelectionData.onSelectionChanged != null) - layerSelectionData.onSelectionChanged(layerSelectionData.serializedObject); - - layerSelectionData.serializedObject.ApplyModifiedProperties(); - - if (layerSelectionData.targets is Light2D[]) - { - foreach (Light2D light in layerSelectionData.targets) - { - if (light != null && light.lightType == Light2D.LightType.Global) - Light2DManager.ErrorIfDuplicateGlobalLight(light); - } - } - } - - void OnNoSortingLayerSelected(object selectionData) - { - m_ApplyToSortingLayersList.Clear(); - UpdateApplyToSortingLayersArray(selectionData); - } - - void OnAllSortingLayersSelected(object selectionData) - { - m_ApplyToSortingLayersList.Clear(); - m_ApplyToSortingLayersList.AddRange(m_AllSortingLayers.Select(x => x.id)); - UpdateApplyToSortingLayersArray(selectionData); - } - - void OnSortingLayerSelected(object layerSelectionDataObject) - { - - LayerSelectionData layerSelectionData = (LayerSelectionData)layerSelectionDataObject; - - int layerID = (int)layerSelectionData.layerID; - - if (m_ApplyToSortingLayersList.Contains(layerID)) - m_ApplyToSortingLayersList.RemoveAll(id => id == layerID); - else - m_ApplyToSortingLayersList.Add(layerID); - - UpdateApplyToSortingLayersArray(layerSelectionDataObject); - } - - public void OnTargetSortingLayers(SerializedObject serializedObject, Object[] targets, GUIContent labelContent, System.Action selectionChangedCallback) - { - Rect totalPosition = EditorGUILayout.GetControlRect(); - GUIContent actualLabel = EditorGUI.BeginProperty(totalPosition, labelContent, m_ApplyToSortingLayers); - Rect position = EditorGUI.PrefixLabel(totalPosition, actualLabel); - - m_ApplyToSortingLayersList.Clear(); - int applyToSortingLayersSize = m_ApplyToSortingLayers.arraySize; - for (int i = 0; i < applyToSortingLayersSize; ++i) - { - int layerID = m_ApplyToSortingLayers.GetArrayElementAtIndex(i).intValue; - if (SortingLayer.IsValid(layerID)) - m_ApplyToSortingLayersList.Add(layerID); - } - - GUIContent selectedLayers; - if (m_ApplyToSortingLayersList.Count == 1) - selectedLayers = new GUIContent(SortingLayer.IDToName(m_ApplyToSortingLayersList[0])); - else if (m_ApplyToSortingLayersList.Count == m_AllSortingLayers.Length) - selectedLayers = Styles.sortingLayerAll; - else if (m_ApplyToSortingLayersList.Count == 0) - selectedLayers = Styles.sortingLayerNone; - else - selectedLayers = Styles.sortingLayerMixed; - - if (EditorGUI.DropdownButton(position, selectedLayers, FocusType.Keyboard, EditorStyles.popup)) - { - GenericMenu menu = new GenericMenu(); - menu.allowDuplicateNames = true; - - LayerSelectionData layerSelectionData = new LayerSelectionData(serializedObject, 0, targets, selectionChangedCallback); - menu.AddItem(Styles.sortingLayerNone, m_ApplyToSortingLayersList.Count == 0, OnNoSortingLayerSelected, layerSelectionData); - menu.AddItem(Styles.sortingLayerAll, m_ApplyToSortingLayersList.Count == m_AllSortingLayers.Length, OnAllSortingLayersSelected, layerSelectionData); - menu.AddSeparator(""); - - for (int i = 0; i < m_AllSortingLayers.Length; ++i) - { - var sortingLayer = m_AllSortingLayers[i]; - layerSelectionData = new LayerSelectionData(serializedObject, sortingLayer.id, targets, selectionChangedCallback); - menu.AddItem(m_AllSortingLayerNames[i], m_ApplyToSortingLayersList.Contains(sortingLayer.id), OnSortingLayerSelected, layerSelectionData); - } - - menu.DropDown(position); - } - - EditorGUI.EndProperty(); - } - } -} +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + internal class SortingLayerDropDown + { + private class LayerSelectionData + { + public SerializedObject serializedObject; + public Object[] targets; + public int layerID; + public System.Action onSelectionChanged; + + public LayerSelectionData(SerializedObject so, int lid, Object[] tgts, System.Action selectionChangedCallback) + { + serializedObject = so; + layerID = lid; + targets = tgts; + onSelectionChanged = selectionChangedCallback; + } + } + + private static class Styles + { + public static GUIContent sortingLayerAll = EditorGUIUtility.TrTextContent("All"); + public static GUIContent sortingLayerNone = EditorGUIUtility.TrTextContent("None"); + public static GUIContent sortingLayerMixed = EditorGUIUtility.TrTextContent("Mixed..."); + } + + SortingLayer[] m_AllSortingLayers; + GUIContent[] m_AllSortingLayerNames; + List m_ApplyToSortingLayersList; + SerializedProperty m_ApplyToSortingLayers; + + public void OnEnable(SerializedObject serializedObject, string propertyName) + { + m_ApplyToSortingLayers = serializedObject.FindProperty(propertyName); + m_ApplyToSortingLayersList = new List(m_ApplyToSortingLayers.arraySize); + + m_AllSortingLayers = SortingLayer.layers; + m_AllSortingLayerNames = m_AllSortingLayers.Select(x => new GUIContent(x.name)).ToArray(); + } + + void UpdateApplyToSortingLayersArray(object layerSelectionDataObject) + { + LayerSelectionData layerSelectionData = (LayerSelectionData)layerSelectionDataObject; + + m_ApplyToSortingLayers.ClearArray(); + for (int i = 0; i < m_ApplyToSortingLayersList.Count; ++i) + { + m_ApplyToSortingLayers.InsertArrayElementAtIndex(i); + m_ApplyToSortingLayers.GetArrayElementAtIndex(i).intValue = m_ApplyToSortingLayersList[i]; + } + + if (layerSelectionData.onSelectionChanged != null) + layerSelectionData.onSelectionChanged(layerSelectionData.serializedObject); + + layerSelectionData.serializedObject.ApplyModifiedProperties(); + + if (layerSelectionData.targets is Light2D[]) + { + foreach (Light2D light in layerSelectionData.targets) + { + if (light != null && light.lightType == Light2D.LightType.Global) + Light2DManager.ErrorIfDuplicateGlobalLight(light); + } + } + } + + void OnNoSortingLayerSelected(object selectionData) + { + m_ApplyToSortingLayersList.Clear(); + UpdateApplyToSortingLayersArray(selectionData); + } + + void OnAllSortingLayersSelected(object selectionData) + { + m_ApplyToSortingLayersList.Clear(); + m_ApplyToSortingLayersList.AddRange(m_AllSortingLayers.Select(x => x.id)); + UpdateApplyToSortingLayersArray(selectionData); + } + + void OnSortingLayerSelected(object layerSelectionDataObject) + { + LayerSelectionData layerSelectionData = (LayerSelectionData)layerSelectionDataObject; + + int layerID = (int)layerSelectionData.layerID; + + if (m_ApplyToSortingLayersList.Contains(layerID)) + m_ApplyToSortingLayersList.RemoveAll(id => id == layerID); + else + m_ApplyToSortingLayersList.Add(layerID); + + UpdateApplyToSortingLayersArray(layerSelectionDataObject); + } + + public void OnTargetSortingLayers(SerializedObject serializedObject, Object[] targets, GUIContent labelContent, System.Action selectionChangedCallback) + { + Rect totalPosition = EditorGUILayout.GetControlRect(); + GUIContent actualLabel = EditorGUI.BeginProperty(totalPosition, labelContent, m_ApplyToSortingLayers); + Rect position = EditorGUI.PrefixLabel(totalPosition, actualLabel); + + m_ApplyToSortingLayersList.Clear(); + int applyToSortingLayersSize = m_ApplyToSortingLayers.arraySize; + for (int i = 0; i < applyToSortingLayersSize; ++i) + { + int layerID = m_ApplyToSortingLayers.GetArrayElementAtIndex(i).intValue; + if (SortingLayer.IsValid(layerID)) + m_ApplyToSortingLayersList.Add(layerID); + } + + GUIContent selectedLayers; + if (m_ApplyToSortingLayersList.Count == 1) + selectedLayers = new GUIContent(SortingLayer.IDToName(m_ApplyToSortingLayersList[0])); + else if (m_ApplyToSortingLayersList.Count == m_AllSortingLayers.Length) + selectedLayers = Styles.sortingLayerAll; + else if (m_ApplyToSortingLayersList.Count == 0) + selectedLayers = Styles.sortingLayerNone; + else + selectedLayers = Styles.sortingLayerMixed; + + if (EditorGUI.DropdownButton(position, selectedLayers, FocusType.Keyboard, EditorStyles.popup)) + { + GenericMenu menu = new GenericMenu(); + menu.allowDuplicateNames = true; + + LayerSelectionData layerSelectionData = new LayerSelectionData(serializedObject, 0, targets, selectionChangedCallback); + menu.AddItem(Styles.sortingLayerNone, m_ApplyToSortingLayersList.Count == 0, OnNoSortingLayerSelected, layerSelectionData); + menu.AddItem(Styles.sortingLayerAll, m_ApplyToSortingLayersList.Count == m_AllSortingLayers.Length, OnAllSortingLayersSelected, layerSelectionData); + menu.AddSeparator(""); + + for (int i = 0; i < m_AllSortingLayers.Length; ++i) + { + var sortingLayer = m_AllSortingLayers[i]; + layerSelectionData = new LayerSelectionData(serializedObject, sortingLayer.id, targets, selectionChangedCallback); + menu.AddItem(m_AllSortingLayerNames[i], m_ApplyToSortingLayersList.Contains(sortingLayer.id), OnSortingLayerSelected, layerSelectionData); + } + + menu.DropDown(position); + } + + EditorGUI.EndProperty(); + } + } +} diff --git a/Editor/2D/SortingLayerDropDown.cs.meta b/Editor/2D/SortingLayerDropDown.cs.meta index 59f23fa..019e1ce 100644 --- a/Editor/2D/SortingLayerDropDown.cs.meta +++ b/Editor/2D/SortingLayerDropDown.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 35e51b3cab2b88440b5791f70c01c09c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 35e51b3cab2b88440b5791f70c01c09c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AnimationClipUpgrader.cs b/Editor/AnimationClipUpgrader.cs new file mode 100644 index 0000000..bf8fd62 --- /dev/null +++ b/Editor/AnimationClipUpgrader.cs @@ -0,0 +1,696 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor.Animations; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.Playables; +using UnityEngine.Rendering; +using IMaterial = UnityEditor.Rendering.UpgradeUtility.IMaterial; +using UID = UnityEditor.Rendering.UpgradeUtility.UID; + +namespace UnityEditor.Rendering +{ + /// + /// A class containing static methods for updating assets with bindings for properties. + /// + /// + /// Animation clips store bindings for material properties by path name, but don't know whether those properties exist on their dependents. + /// Because property names did not change uniformly in the material/shader upgrade process, it is not possible to patch path names indiscriminately. + /// This class provides utilities for discovering how clips are used, so users can make decisions about whether or not to then update them. + /// It has the limitation that it only knows about: + /// - Clips that are directly referenced by an component + /// - Clips referenced by an used by an component + /// - Clips that are sub-assets of a used by a component with a single binding + /// It does not know about clips that might be referenced in other ways for run-time reassignment. + /// Recommended usage is to call from a menu item callback. + /// The utility can also provide faster, more reliable results if it knows what was used to upgrade specific materials. + /// + static partial class AnimationClipUpgrader + { + static readonly Regex k_MatchMaterialPropertyName = new Regex(@"material.(\w+)(\.\w+)?", RegexOptions.Compiled); + + /// + /// Determines whether the specified is for a material property. + /// + /// Internal only for testability. + /// An . + /// true if the binding is for a material property; false otherwise. + internal static bool IsMaterialBinding(EditorCurveBinding b) => + (b.type?.IsSubclassOf(typeof(Renderer)) ?? false) + && !string.IsNullOrEmpty(b.propertyName) + && k_MatchMaterialPropertyName.IsMatch(b.propertyName); + + static readonly IReadOnlyCollection k_ColorAttributeSuffixes = + new HashSet(new[] { ".r", ".g", ".b", ".a" }); + + /// + /// Infer a shader property name and type from an . + /// + /// Internal only for testability. + /// A binding presumed to map to a material property. (See also .) + /// A shader property name, and a guess of what type of shader property it targets. + internal static (string Name, ShaderPropertyType Type) InferShaderProperty(EditorCurveBinding binding) + { + var match = k_MatchMaterialPropertyName.Match(binding.propertyName); + var propertyName = match.Groups[1].Value; + var propertyType = match.Groups[2].Value; + return (propertyName, + k_ColorAttributeSuffixes.Contains(propertyType) ? ShaderPropertyType.Color : ShaderPropertyType.Float); + } + + /// + /// Gets asset data for all clip assets at the specified paths, which contain bindings for material properties. + /// (See also and .) + /// + /// Paths to assets containing . + /// + /// Lookup table mapping to its asset path, bindings, property rename table, and usage. + /// (Use to initialize rename table and usage.) + /// + internal static IDictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary PropertyRenames) + > GetAssetDataForClipsFiltered( + IEnumerable clipPaths + ) + { + var result = new Dictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary PropertyRenames) + >(); + foreach (var clipPath in clipPaths) + { + foreach (var asset in AssetDatabase.LoadAllAssetsAtPath(clipPath)) + { + if (!(asset is AnimationClip clip)) + continue; + + var bindings = AnimationUtility.GetCurveBindings(clip).Where(IsMaterialBinding).ToArray(); + if (bindings.Length == 0) + continue; + + result[(AnimationClipProxy)clip] = + (clipPath, bindings, SerializedShaderPropertyUsage.Unknown, new Dictionary()); + } + } + + return result; + } + + /// + /// Get dependency mappings between and their dependents. + /// + /// Paths to clips to consider. (See also .) + /// Paths to assets to consider. + /// Mapping of clip paths to paths of their dependents. + /// Mapping of asset paths to their clip dependencies. + /// The type of asset path. + internal static void GetClipDependencyMappings( + IEnumerable clips, + IEnumerable assets, + out IReadOnlyDictionary> clipToDependentAssets, + out IReadOnlyDictionary> assetToClipDependencies + ) where T : struct, IAssetPath + { + // ensure there are no duplicate keys + clips = new HashSet(clips); + assets = new HashSet(assets); + + // create mutable builders + var clipsDependentsBuilder = clips.ToDictionary(c => c, c => new HashSet()); + var assetsBuilder = new Dictionary>(); + + // build dependency tables + foreach (var asset in assets) + { + assetsBuilder[asset] = new HashSet(); + + foreach (var dependencyPath in AssetDatabase.GetDependencies(asset.Path)) + { + if (!clipsDependentsBuilder.TryGetValue(dependencyPath, out var dependents)) + continue; + + dependents.Add(asset); + assetsBuilder[asset].Add(dependencyPath); + } + } + + // return readonly results + clipToDependentAssets = + clipsDependentsBuilder.ToDictionary(kv => kv.Key, kv => kv.Value as IReadOnlyCollection); + assetToClipDependencies = + assetsBuilder.ToDictionary(kv => kv.Key, kv => kv.Value as IReadOnlyCollection); + } + + // reusable buffers + static readonly List s_AnimationBuffer = new List(8); + static readonly List s_AnimatorBuffer = new List(8); + static readonly List s_CustomAnimationBuffer = new List(8); + static readonly List s_PlayableDirectorBuffer = new List(8); + + /// + /// Get information about a clip's usage among its dependent scenes to determine whether or not it should be upgraded. + /// + /// + /// A table mapping clip asset paths, to asset paths of their dependent prefabs. + /// (See .) + /// + /// + /// A table mapping prefab asset paths, to asset paths of their clip dependencies. + /// (See .) + /// + /// + /// A table mapping clips to other data about them. (See also .) + /// + /// + /// A table of new shader names and all known upgrade paths to them in the target pipeline. + /// (See also .) + /// + /// + /// Optional table of materials known to have gone through a specific upgrade path. + /// + /// + /// Optional functor to display a progress bar. + /// + internal static void GatherClipsUsageInDependentPrefabs( + IReadOnlyDictionary> clipDependents, + // TODO: right now, clip dependencies are gathered in Animation/Animator, so this may not be needed... + IReadOnlyDictionary> assetDependencies, + IDictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary PropertyRenames) + > clipData, + IReadOnlyDictionary> allUpgradePathsToNewShaders, + IReadOnlyDictionary upgradePathsUsedByMaterials = default, + Func progressFunctor = null + ) + { + int clipIndex = 0; + int totalNumberOfClips = clipDependents.Count; + + // check all dependents for usage + foreach (var kv in clipDependents) + { + float currentProgress = (float)++clipIndex / totalNumberOfClips; + if (progressFunctor != null && progressFunctor($"({clipIndex} of {totalNumberOfClips}) {kv.Key.Path}", currentProgress)) + break; + + foreach (var prefabPath in kv.Value) + { + var go = AssetDatabase.LoadAssetAtPath(prefabPath); + GatherClipsUsageForGameObject(go, clipData, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials); + } + } + } + + /// + /// Get information about a clip's usage among its dependent scenes to determine whether or not it should be upgraded. + /// + /// + /// Because this method will open scenes to search for usages, it is recommended you first prompt for user input. + /// It is also a good idea to first call to generate usage data. + /// Clips that are already known to be unsafe for upgrading based on their prefab usage can be skipped here. + /// + /// + /// A table mapping clip asset paths, to asset paths of their dependent scenes. + /// (See .) + /// + /// + /// A table mapping scene asset paths, to asset paths of their clip dependencies. + /// (See .) + /// + /// + /// A table mapping clips to other data about them. (See also .) + /// + /// + /// A table of new shader names and all known upgrade paths to them in the target pipeline. + /// (See also .) + /// + /// + /// Optional table of materials known to have gone through a specific upgrade path. + /// + /// + /// Optional functor to display a progress bar. + /// + internal static void GatherClipsUsageInDependentScenes( + IReadOnlyDictionary> clipDependents, + // TODO: right now, clip dependencies are gathered in Animation/Animator, so this may not be needed... + IReadOnlyDictionary> assetDependencies, + IDictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary + PropertyRenames) + > clipData, + IReadOnlyDictionary> allUpgradePathsToNewShaders, + IReadOnlyDictionary upgradePathsUsedByMaterials = default, + Func progressFunctor = null + ) + { + int clipIndex = 0; + int totalNumberOfClips = clipDependents.Count; + + // check all dependents for usage + foreach (var kv in clipDependents) + { + float currentProgress = (float)++clipIndex / totalNumberOfClips; + if (progressFunctor != null && progressFunctor($"({clipIndex} of {totalNumberOfClips}) {kv.Key.Path}", currentProgress)) + break; + + foreach (var scenePath in kv.Value) + { + var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); + foreach (var go in scene.GetRootGameObjects()) + GatherClipsUsageForGameObject(go, clipData, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials); + } + } + } + + /// + /// Update usage information about the specified clips in the clip data table. + /// + /// A prefab, or a in a scene. + /// + /// A table mapping clips to other data about them. (See also .) + /// + /// + /// A table of new shader names and all known upgrade paths to them in the target pipeline. + /// (See also .) + /// + /// + /// Optional table of materials known to have gone through a specific upgrade path. + /// + static void GatherClipsUsageForGameObject( + GameObject go, + IDictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary PropertyRenames) + > clipData, + IReadOnlyDictionary> allUpgradePathsToNewShaders, + IReadOnlyDictionary upgradePathsUsedByMaterials = default + ) + { + go.GetComponentsInChildren(true, s_AnimationBuffer); + go.GetComponentsInChildren(true, s_AnimatorBuffer); + go.GetComponentsInChildren(true, s_CustomAnimationBuffer); + + // first check clip usage among GameObjects with legacy Animation + var gameObjects = new HashSet(s_AnimationBuffer.Select(a => a.gameObject) + .Union(s_AnimatorBuffer.Select(a => a.gameObject)) + .Union(s_CustomAnimationBuffer.Where(a => a is Component).Select(a => ((Component)a).gameObject))); + + foreach (var gameObject in gameObjects) + { + var clips = AnimationUtility.GetAnimationClips(gameObject).Select(clip => (IAnimationClip)(AnimationClipProxy)clip); + + GatherClipsUsageForAnimatedHierarchy( + gameObject.transform, clips, clipData, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials + ); + } + + // next check clip usage among GameObjects with PlayableDirector + go.GetComponentsInChildren(true, s_PlayableDirectorBuffer); + foreach (var playableDirector in s_PlayableDirectorBuffer) + { + var playableAsset = playableDirector.playableAsset; + if (playableAsset == null) + continue; + + var assetPath = AssetDatabase.GetAssetPath(playableAsset); + + // get all clip sub-assets + var clips = new HashSet( + AssetDatabase.LoadAllAssetsAtPath(assetPath) + .Where(asset => asset is AnimationClip) + .Select(asset => (IAnimationClip)(AnimationClipProxy)(asset as AnimationClip)) + ); + + // get all clip dependency-assets + // this will not handle nested clips in FBX like assets, but these are less likely to be editable + clips.UnionWith(AssetDatabase.GetDependencies(assetPath) + .Select(AssetDatabase.LoadAssetAtPath) + .Where(asset => asset is AnimationClip) + .Select(asset => (IAnimationClip)(AnimationClipProxy)asset)); + + // check if the value of a binding is an animator, and examines clip usage relative to it + // this is imprecise, but is suitable to catch the majority of cases (i.e., a single animator binding) + using (var so = new SerializedObject(playableDirector)) + { + var clipsProp = so.FindProperty("m_SceneBindings"); + for (int i = 0, count = clipsProp.arraySize; i < count; ++i) + { + var elementProp = clipsProp.GetArrayElementAtIndex(i); + var value = elementProp.FindPropertyRelative("value"); + if (value.objectReferenceValue is Animator animator) + { + GatherClipsUsageForAnimatedHierarchy( + animator.transform, clips, clipData, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials + ); + } + } + } + } + + // release UnityObject references + s_AnimationBuffer.Clear(); + s_AnimatorBuffer.Clear(); + s_CustomAnimationBuffer.Clear(); + s_PlayableDirectorBuffer.Clear(); + } + + // reusable buffers + static readonly List s_RendererBuffer = new List(8); + + static readonly Dictionary Materials)> s_RenderersByPath = + new Dictionary Materials)>(); + + /// + /// Update usage information about the specified clips in the clip data table. + /// + /// The root of the animated hierarchy (i.e., object with Animation or Animator). + /// Collection of animation clips + /// + /// A table mapping clips to other data about them. (See also .) + /// + /// + /// A table of new shader names and all known upgrade paths to them in the target pipeline. + /// (See also .) + /// + /// + /// Optional table of materials known to have gone through a specific upgrade path. + /// + static void GatherClipsUsageForAnimatedHierarchy( + Transform root, + IEnumerable clips, + IDictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary PropertyRenames) + > clipData, + IReadOnlyDictionary> allUpgradePathsToNewShaders, + IReadOnlyDictionary upgradePathsUsedByMaterials + ) + { + // TODO: report paths of specific assets that contribute to problematic results? + + // find all renderers in the animated hierarchy + root.GetComponentsInChildren(true, s_RendererBuffer); + foreach (var renderer in s_RendererBuffer) + { + var path = AnimationUtility.CalculateTransformPath(renderer.transform, root); + var m = ListPool.Get(); + var r = (RendererProxy)renderer; + r.GetSharedMaterials(m); + s_RenderersByPath[path] = (r, m); + } + + // if there are any renderers, check all clips for usage + if (s_RendererBuffer.Count > 0) + { + foreach (var clip in clips) + GatherClipUsage(clip, clipData, s_RenderersByPath, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials); + } + + // release UnityObject references + s_RendererBuffer.Clear(); + foreach (var (_, materials) in s_RenderersByPath.Values) + ListPool.Release(materials); + s_RenderersByPath.Clear(); + } + + /// + /// Update usage information about the specified clip in the clip data table. + /// + /// + /// This method works by looking at shaders used by materials assigned to the specified renderers. + /// Usage and property renames for the clip are updated, if a binding in the clip matches an upgrader. + /// Internal only for testability. + /// + /// An animation clip. + /// + /// A table mapping clips to other data about them. (See also .) + /// + /// + /// A table mapping transform paths of renderers to lists of the materials they use. + /// + /// + /// A table of new shader names and all known upgrade paths to them in the target pipeline. + /// (See also .) + /// + /// + /// Optional table of materials known to have gone through a specific upgrade path. + /// + internal static void GatherClipUsage( + IAnimationClip clip, + IDictionary< + IAnimationClip, + (ClipPath Path, EditorCurveBinding[] Bindings, SerializedShaderPropertyUsage Usage, IDictionary PropertyRenames) + > clipData, + IReadOnlyDictionary Materials)> renderersByPath, + IReadOnlyDictionary> allUpgradePathsToNewShaders, + IReadOnlyDictionary upgradePathsUsedByMaterials + ) + { + // exit if clip is unknown; it may have been filtered at an earlier stage + if (!clipData.TryGetValue(clip, out var data)) + return; + + // see if any animated material bindings in the clip refer to renderers in animated hierarchy + foreach (var binding in data.Bindings) + { + // skip if binding is not for material, or refers to a nonexistent renderer + if ( + !IsMaterialBinding(binding) + || !renderersByPath.TryGetValue(binding.path, out var rendererData) + ) continue; + + // determine the shader property name and type from the binding + var shaderProperty = InferShaderProperty(binding); + var renameType = shaderProperty.Type == ShaderPropertyType.Color + ? MaterialUpgrader.MaterialPropertyType.Color + : MaterialUpgrader.MaterialPropertyType.Float; + + // material property animations apply to all materials, so check shader usage in all of them + foreach (var material in rendererData.Materials) + { + var usage = UpgradeUtility.GetNewPropertyName( + shaderProperty.Name, + material, + renameType, + allUpgradePathsToNewShaders, + upgradePathsUsedByMaterials, + out var newPropertyName + ); + + // if the property has already been upgraded with a different name, mark the upgrade as ambiguous + if ( + usage == SerializedShaderPropertyUsage.UsedByUpgraded + && data.PropertyRenames.TryGetValue(binding, out var propertyRename) + && propertyRename != newPropertyName + ) + usage |= SerializedShaderPropertyUsage.UsedByAmbiguouslyUpgraded; + + data.Usage |= usage; + data.PropertyRenames[binding] = newPropertyName; + } + } + + clipData[clip] = data; + } + + /// + /// Upgrade the specified clips using the associated property rename table. + /// + /// + /// A table mapping clips to property renaming tables that can be safely applied to their bindings. + /// + /// Do not upgrade clips that have any of these flags set. + /// Collector for all clips that are upgraded. + /// Collector for all clips that are not upgraded. + /// Optional functor to display a progress bar. + internal static void UpgradeClips( + IDictionary PropertyRenames)> clipsToUpgrade, + SerializedShaderPropertyUsage excludeFlags, + HashSet<(IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)> upgraded, + HashSet<(IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)> notUpgraded, + Func progressFunctor = null + ) + { + upgraded.Clear(); + notUpgraded.Clear(); + + int clipIndex = 0; + int totalNumberOfClips = clipsToUpgrade.Count; + + foreach (var kv in clipsToUpgrade) + { + float currentProgress = (float)++clipIndex / totalNumberOfClips; + if (progressFunctor != null && progressFunctor($"({clipIndex} of {totalNumberOfClips}) {kv.Value.Path.Path}", currentProgress)) + break; + + if (kv.Value.Usage == SerializedShaderPropertyUsage.Unknown || (kv.Value.Usage & excludeFlags) != 0) + { + notUpgraded.Add((kv.Key, kv.Value.Path, kv.Value.Usage)); + continue; + } + + var renames = kv.Value.PropertyRenames; + var bindings = kv.Key.GetCurveBindings().Where(IsMaterialBinding).ToArray(); + if (bindings.Length > 0) + { + var newBindings = new EditorCurveBinding[bindings.Length]; + + for (int i = 0; i < bindings.Length; ++i) + { + var binding = bindings[i]; + + newBindings[i] = binding; + if (renames.TryGetValue(binding, out var newName)) + newBindings[i].propertyName = k_MatchMaterialPropertyName.Replace(newBindings[i].propertyName, $"material.{newName}$2"); + } + + kv.Key.ReplaceBindings(bindings, newBindings); + } + + upgraded.Add((kv.Key, kv.Value.Path, kv.Value.Usage)); + } + } + + /// + /// A function to call from a menu item callback, which will upgrade all in the project. + /// + /// All for the current render pipeline. + /// + /// Optional mapping of materials to upgraders they are known to have used. + /// Without this mapping, the method makes inferences about how a material might have been upgraded. + /// Making these inferences is slower and possibly not sensitive to ambiguous upgrade paths. + /// + /// + /// Optional flags to filter out clips that are used in ways that are not safe for upgrading. + /// + public static void DoUpgradeAllClipsMenuItem( + IEnumerable allUpgraders, + string progressBarName, + IReadOnlyDictionary knownUpgradePaths = default, + SerializedShaderPropertyUsage filterFlags = ~(SerializedShaderPropertyUsage.UsedByUpgraded | SerializedShaderPropertyUsage.UsedByNonUpgraded) + ) + { + var clipPaths = AssetDatabase.FindAssets("t:AnimationClip") + .Select(p => (ClipPath)AssetDatabase.GUIDToAssetPath(p)) + .ToArray(); + DoUpgradeClipsMenuItem(clipPaths, allUpgraders, progressBarName, knownUpgradePaths, filterFlags); + } + + static void DoUpgradeClipsMenuItem( + ClipPath[] clipPaths, + IEnumerable allUpgraders, + string progressBarName, + IReadOnlyDictionary upgradePathsUsedByMaterials, + SerializedShaderPropertyUsage filterFlags + ) + { + // exit early if no clips + if (clipPaths?.Length == 0) + return; + + // display dialog box + var dialogMessage = L10n.Tr( + "Upgrading Material curves in AnimationClips assumes you have already upgraded Materials and shaders as needed. " + + "It also requires loading assets that use clips to inspect their usage, which can be a slow process. " + + "Do you want to proceed?" + ); + + if (!EditorUtility.DisplayDialog( + L10n.Tr("Upgrade AnimationClips"), + dialogMessage, + DialogText.proceed, + DialogText.cancel)) + return; + + // only include scene paths if user requested it + var prefabPaths = AssetDatabase.FindAssets("t:Prefab") + .Select(p => (PrefabPath)AssetDatabase.GUIDToAssetPath(p)) + .ToArray(); + var scenePaths = AssetDatabase.FindAssets("t:Scene") + .Select(p => (ScenePath)AssetDatabase.GUIDToAssetPath(p)) + .ToArray(); + + // retrieve clip assets with material animation + var clipData = GetAssetDataForClipsFiltered(clipPaths); + + const float kGatherInPrefabsTotalProgress = 0.33f; + const float kGatherInScenesTotalProgress = 0.66f; + const float kUpgradeClipsTotalProgress = 1f; + + // create table mapping all upgrade paths to new shaders + var allUpgradePathsToNewShaders = UpgradeUtility.GetAllUpgradePathsToShaders(allUpgraders); + + // retrieve interdependencies with prefabs to figure out which clips can be safely upgraded + GetClipDependencyMappings(clipPaths, prefabPaths, out var clipPrefabDependents, out var prefabDependencies); + + GatherClipsUsageInDependentPrefabs( + clipPrefabDependents, prefabDependencies, clipData, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials, + (info, progress) => EditorUtility.DisplayCancelableProgressBar(progressBarName, $"Gathering from prefabs {info}", Mathf.Lerp(0f, kGatherInPrefabsTotalProgress, progress)) + ); + + if (EditorUtility.DisplayCancelableProgressBar(progressBarName, "", kGatherInPrefabsTotalProgress)) + { + EditorUtility.ClearProgressBar(); + return; + } + + // if any scenes should be considered, do the same for clips used by scenes + if (scenePaths.Any()) + { + GetClipDependencyMappings(clipPaths, scenePaths, out var clipSceneDependents, out var sceneDependencies); + GatherClipsUsageInDependentScenes( + clipSceneDependents, sceneDependencies, clipData, allUpgradePathsToNewShaders, upgradePathsUsedByMaterials, + (info, progress) => EditorUtility.DisplayCancelableProgressBar(progressBarName, $"Gathering from scenes {info}", Mathf.Lerp(kGatherInPrefabsTotalProgress, kGatherInScenesTotalProgress, progress)) + ); + } + + if (EditorUtility.DisplayCancelableProgressBar(progressBarName, "", kGatherInScenesTotalProgress)) + { + EditorUtility.ClearProgressBar(); + return; + } + + // patch clips that should be upgraded + var upgraded = new HashSet<(IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)>(); + var notUpgraded = new HashSet<(IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)>(); + + AssetDatabase.StartAssetEditing(); + UpgradeClips( + clipData, filterFlags, upgraded, notUpgraded, + (info, progress) => EditorUtility.DisplayCancelableProgressBar(progressBarName, $"Upgrading clips {info}", Mathf.Lerp(kGatherInScenesTotalProgress, kUpgradeClipsTotalProgress, progress)) + ); + AssetDatabase.SaveAssets(); + AssetDatabase.StopAssetEditing(); + + EditorUtility.ClearProgressBar(); + + // report results + if (upgraded.Count > 0) + { + var successes = upgraded.Select(data => $"- {data.Path}: ({data.Usage})"); + Debug.Log( + "Upgraded the following clips:\n" + + $"{string.Join("\n", successes)}" + ); + } + + if (notUpgraded.Count == clipData.Count) + { + Debug.LogWarning("No clips were upgraded. Did you remember to upgrade materials first?"); + } + else if (notUpgraded.Count > 0) + { + var errors = notUpgraded.Select(data => $"- {data.Path}: ({data.Usage})"); + Debug.LogWarning( + $"Did not modify following clips because they they were used in ways other than {~filterFlags}:\n" + + $"{string.Join("\n", errors)}" + ); + } + } + } +} diff --git a/Editor/AnimationClipUpgrader.cs.meta b/Editor/AnimationClipUpgrader.cs.meta new file mode 100644 index 0000000..b6744ee --- /dev/null +++ b/Editor/AnimationClipUpgrader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa2a59a04711f40438d3880b3c717871 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AnimationClipUpgrader_Types.cs b/Editor/AnimationClipUpgrader_Types.cs new file mode 100644 index 0000000..4994d7d --- /dev/null +++ b/Editor/AnimationClipUpgrader_Types.cs @@ -0,0 +1,108 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Rendering; +using IMaterial = UnityEditor.Rendering.UpgradeUtility.IMaterial; +using MaterialProxy = UnityEditor.Rendering.UpgradeUtility.MaterialProxy; + +namespace UnityEditor.Rendering +{ + /// + /// Internal type definitions for . + /// + /// + /// This class contains two categories of internal types: + /// 1. Proxies for UnityObject assets (used for test mocking and facilitating usage without requiring loading all assets of the given type at once). + /// 2. Asset path wrappers (used for stronger typing and clarity in the API surface). + /// + static partial class AnimationClipUpgrader + { + #region Proxies + + internal interface IAnimationClip + { + AnimationClip Clip { get; } + EditorCurveBinding[] GetCurveBindings(); + void ReplaceBindings(EditorCurveBinding[] oldBindings, EditorCurveBinding[] newBindings); + } + + internal struct AnimationClipProxy : IAnimationClip + { + public AnimationClip Clip { get; set; } + public EditorCurveBinding[] GetCurveBindings() => AnimationUtility.GetCurveBindings(Clip); + public void ReplaceBindings(EditorCurveBinding[] oldBindings, EditorCurveBinding[] newBindings) + { + var curves = new AnimationCurve[oldBindings.Length]; + + for (int i = 0, count = oldBindings.Length; i < count; ++i) + curves[i] = AnimationUtility.GetEditorCurve(Clip, oldBindings[i]); + + AnimationUtility.SetEditorCurves(Clip, oldBindings, new AnimationCurve[oldBindings.Length]); + AnimationUtility.SetEditorCurves(Clip, newBindings, curves); + } + + public static implicit operator AnimationClip(AnimationClipProxy proxy) => proxy.Clip; + public static implicit operator AnimationClipProxy(AnimationClip clip) => new AnimationClipProxy { Clip = clip }; + public override string ToString() => Clip.ToString(); + } + + internal interface IRenderer + { + } + + internal struct RendererProxy : IRenderer + { + Renderer m_Renderer; + public void GetSharedMaterials(List materials) + { + materials.Clear(); + var m = ListPool.Get(); + m_Renderer.GetSharedMaterials(m); + materials.AddRange(m.Select(mm => (MaterialProxy)mm).Cast()); + ListPool.Release(m); + } + + public static implicit operator Renderer(RendererProxy proxy) => proxy.m_Renderer; + public static implicit operator RendererProxy(Renderer renderer) => new RendererProxy { m_Renderer = renderer }; + public override string ToString() => m_Renderer.ToString(); + } + + #endregion + + #region AssetPath Wrappers + + internal interface IAssetPath + { + string Path { get; } + } + + internal struct ClipPath : IAssetPath + { + public string Path { get; set; } + public static implicit operator string(ClipPath clip) => clip.Path; + public static implicit operator ClipPath(string path) => new ClipPath { Path = path }; + public static implicit operator ClipPath(AnimationClip clip) => new ClipPath { Path = AssetDatabase.GetAssetPath(clip) }; + public override string ToString() => Path; + } + + internal struct PrefabPath : IAssetPath + { + public string Path { get; set; } + public static implicit operator string(PrefabPath prefab) => prefab.Path; + public static implicit operator PrefabPath(string path) => new PrefabPath { Path = path }; + public static implicit operator PrefabPath(GameObject go) => new PrefabPath { Path = AssetDatabase.GetAssetPath(go) }; + public override string ToString() => Path; + } + + internal struct ScenePath : IAssetPath + { + public string Path { get; set; } + public static implicit operator string(ScenePath scene) => scene.Path; + public static implicit operator ScenePath(string path) => new ScenePath { Path = path }; + public static implicit operator ScenePath(SceneAsset scene) => new ScenePath { Path = AssetDatabase.GetAssetPath(scene) }; + public override string ToString() => Path; + } + + #endregion + } +} diff --git a/Editor/AnimationClipUpgrader_Types.cs.meta b/Editor/AnimationClipUpgrader_Types.cs.meta new file mode 100644 index 0000000..0dc2378 --- /dev/null +++ b/Editor/AnimationClipUpgrader_Types.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bd2d05317ed144dab0dc8004f5047fd7 +timeCreated: 1614910810 \ No newline at end of file diff --git a/Editor/AssemblyInfo.cs b/Editor/AssemblyInfo.cs index 36d73ec..4b57b44 100644 --- a/Editor/AssemblyInfo.cs +++ b/Editor/AssemblyInfo.cs @@ -1,5 +1,7 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("UniversalGraphicsTests")] -[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor.Tests")] -[assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.Universal.Editor")] +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // permit using internal interfaces with Moq +[assembly: InternalsVisibleTo("UniversalGraphicsTests")] +[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor.Tests")] +[assembly: InternalsVisibleTo("Unity.Testing.SRP.Universal-Upgrade.Editor")] +[assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.Universal.Editor")] diff --git a/Editor/AssemblyInfo.cs.meta b/Editor/AssemblyInfo.cs.meta index cf71e6a..4cd770a 100644 --- a/Editor/AssemblyInfo.cs.meta +++ b/Editor/AssemblyInfo.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: ee81cfba546d646ca9b7a9394f78b66b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: ee81cfba546d646ca9b7a9394f78b66b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors.meta b/Editor/AssetPostProcessors.meta index 65efc7d..5397322 100644 --- a/Editor/AssetPostProcessors.meta +++ b/Editor/AssetPostProcessors.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 80a17677e8c9b3040a01d400cf19819f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 80a17677e8c9b3040a01d400cf19819f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs b/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs index 0c91ba7..dbad706 100644 --- a/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs +++ b/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs @@ -1,341 +1,342 @@ -using UnityEngine; -using UnityEditor.AssetImporters; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Rendering.Universal -{ - class AutodeskInteractiveMaterialImport : AssetPostprocessor - { - static readonly uint k_Version = 1; - static readonly int k_Order = 3; - public override uint GetVersion() - { - return k_Version; - } - public override int GetPostprocessOrder() - { - return k_Order; - } - - public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) - { - var pipelineAsset = GraphicsSettings.currentRenderPipeline; - if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) - return; - - if (IsAutodeskInteractiveMaterial(description)) - { - float floatProperty; - Vector4 vectorProperty; - TexturePropertyDescription textureProperty; - - bool isMasked = description.TryGetProperty("mask_threshold",out floatProperty); - bool isTransparent = description.TryGetProperty("opacity",out floatProperty); - - Shader shader; - if (isMasked) - shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveMaskedShader; - else if (isTransparent) - shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveTransparentShader; - else - shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveShader; - - if (shader == null) - return; - - material.shader = shader; - foreach (var clip in clips) - { - clip.ClearCurves(); - } - - if (description.TryGetProperty("base_color", out vectorProperty)) - material.SetColor("_Color", vectorProperty); - if (description.TryGetProperty("emissive", out vectorProperty)) - material.SetColor("_EmissionColor", vectorProperty); - - if (description.TryGetProperty("roughness", out floatProperty)) - material.SetFloat("_Roughness", floatProperty); - - if (description.TryGetProperty("metallic", out floatProperty)) - material.SetFloat("_Metallic", floatProperty); - - if (description.TryGetProperty("uvTransform", out vectorProperty)) - { - material.SetVector("_UvOffset", new Vector4(vectorProperty.x, vectorProperty.y, .0f, .0f)); - material.SetVector("_UvTiling", new Vector4(vectorProperty.w, vectorProperty.z, .0f, .0f)); - } - - if (description.TryGetProperty("TEX_color_map", out textureProperty)) - { - material.SetTexture("_MainTex", textureProperty.texture); - material.SetFloat("_UseColorMap", 1.0f); - } - else - { - material.SetFloat("_UseColorMap", 0.0f); - } - - if (description.TryGetProperty("TEX_normal_map", out textureProperty)) - { - material.SetTexture("_BumpMap", textureProperty.texture); - material.SetFloat("_UseNormalMap", 1.0f); - } - else - { - material.SetFloat("_UseNormalMap", 0.0f); - } - - if (description.TryGetProperty("TEX_roughness_map", out textureProperty)) - { - material.SetTexture("RoughnessMap", textureProperty.texture); - material.SetFloat("_UseRoughnessMap", 1.0f); - } - else - { - material.SetFloat("_UseRoughnessMap", 0.0f); - } - - if (description.TryGetProperty("TEX_metallic_map", out textureProperty)) - { - material.SetTexture("_MetallicMap", textureProperty.texture); - material.SetFloat("_UseMetallicMap", 1.0f); - } - else - { - material.SetFloat("_UseMetallicMap", 0.0f); - } - - if (description.TryGetProperty("TEX_emissive_map", out textureProperty)) - { - material.SetTexture("_EmissionMap", textureProperty.texture); - material.SetFloat("_UseEmissiveMap", 1.0f); - } - else - { - material.SetFloat("_UseEmissiveMap", 0.0f); - } - - if (description.TryGetProperty("hasTransparencyTexture", out floatProperty)) - material.SetFloat("_UseOpacityMap", floatProperty); - - if (description.TryGetProperty("transparencyMaskThreshold", out floatProperty)) - material.SetFloat("_OpacityThreshold", floatProperty); - - if (description.TryGetProperty("TEX_ao_map", out textureProperty)) - { - var tex = AssetDatabase.LoadAssetAtPath(textureProperty.relativePath); - material.SetTexture("AoMap", tex); - material.SetFloat("UseAoMap", 1.0f); - } - else - { - material.SetFloat("UseAoMap", 0.0f); - } - - RemapColorCurves(description, clips, "base_color", "_Color"); - RemapCurve(description, clips, "mask_threshold", "_Cutoff"); - RemapCurve(description, clips, "metallic", "_Metallic"); - RemapCurve(description, clips, "roughness", "_Glossiness"); - - for (int i = 0; i < clips.Length; i++) - { - if (description.HasAnimationCurveInClip(clips[i].name, "uv_scale.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_scale.y")) - { - AnimationCurve curve; - if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.x", out curve)) - clips[i].SetCurve("", typeof(Material), "_UvTiling.x", curve); - else - clips[i].SetCurve("", typeof(Material), "_UvTiling.x", AnimationCurve.Constant(0.0f, 1.0f, 1.0f)); - - if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.y", out curve)) - clips[i].SetCurve("", typeof(Material), "_UvTiling.y", curve); - else - clips[i].SetCurve("", typeof(Material), "_UvTiling.y", AnimationCurve.Constant(0.0f, 1.0f, 1.0f)); - } - - if (description.HasAnimationCurveInClip(clips[i].name, "uv_offset.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_offset.y")) - { - AnimationCurve curve; - if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.x", out curve)) - clips[i].SetCurve("", typeof(Material), "_UvOffset.x", curve); - else - clips[i].SetCurve("", typeof(Material), "_UvOffset.x", AnimationCurve.Constant(0.0f, 1.0f, 0.0f)); - - if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.y", out curve)) - { - ConvertKeys(curve, ConvertFloatNegate); - clips[i].SetCurve("", typeof(Material), "_UvOffset.y", curve); - } - else - clips[i].SetCurve("", typeof(Material), "_UvOffset.y", AnimationCurve.Constant(0.0f, 1.0f, 0.0f)); - } - } - - if (description.HasAnimationCurve("emissive_intensity")) - { - Vector4 emissiveColor; - description.TryGetProperty("emissive", out emissiveColor); - - for (int i = 0; i < clips.Length; i++) - { - AnimationCurve curve; - description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve); - // remap emissive intensity to emission color - clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve); - } - } - else if (description.TryGetProperty("emissive", out vectorProperty)) - { - if (vectorProperty.x > 0.0f || vectorProperty.y > 0.0f || vectorProperty.z > 0.0f) - { - material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; - material.EnableKeyword("_EMISSION"); - } - - if (description.TryGetProperty("emissive_intensity", out floatProperty)) - { - vectorProperty *= floatProperty; - } - - material.SetColor("_EmissionColor", vectorProperty); - - - if (description.HasAnimationCurve("emissive.x")) - { - if (description.HasAnimationCurve("emissive_intensity")) - { - // combine color and intensity. - for (int i = 0; i < clips.Length; i++) - { - AnimationCurve curve; - AnimationCurve intensityCurve; - description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out intensityCurve); - - description.TryGetAnimationCurve(clips[i].name, "emissive.x", out curve); - MultiplyCurves(curve, intensityCurve); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve); - - description.TryGetAnimationCurve(clips[i].name, "emissive.y", out curve); - MultiplyCurves(curve, intensityCurve); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve); - - description.TryGetAnimationCurve(clips[i].name, "emissive.z", out curve); - MultiplyCurves(curve, intensityCurve); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve); - } - } - else - { - RemapColorCurves(description, clips, "emissive", "_EmissionColor"); - } - } - else if (description.HasAnimationCurve("emissive_intensity")) - { - Vector4 emissiveColor; - description.TryGetProperty("emissive", out emissiveColor); - - for (int i = 0; i < clips.Length; i++) - { - AnimationCurve curve; - description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve); - // remap emissive intensity to emission color - AnimationCurve curveR = new AnimationCurve(); - ConvertAndCopyKeys(curveR, curve, value => ConvertFloatMultiply(emissiveColor.x, value)); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curveR); - - AnimationCurve curveG = new AnimationCurve(); - ConvertAndCopyKeys(curveG, curve, value => ConvertFloatMultiply(emissiveColor.y, value)); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curveG); - - AnimationCurve curveB = new AnimationCurve(); - ConvertAndCopyKeys(curveB, curve, value => ConvertFloatMultiply(emissiveColor.z, value)); - clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curveB); - } - } - } - } - } - - static bool IsAutodeskInteractiveMaterial(MaterialDescription description) - { - return description.TryGetProperty("renderAPI", out string stringValue) && stringValue == "SFX_PBS_SHADER"; - } - - static void ConvertKeys(AnimationCurve curve, System.Func convertionDelegate) - { - Keyframe[] keyframes = curve.keys; - for (int i = 0; i < keyframes.Length; i++) - { - keyframes[i].value = convertionDelegate(keyframes[i].value); - } - curve.keys = keyframes; - } - - static void ConvertAndCopyKeys(AnimationCurve curveDest, AnimationCurve curveSource, System.Func convertionDelegate) - { - for (int i = 0; i < curveSource.keys.Length; i++) - { - var sourceKey = curveSource.keys[i]; - curveDest.AddKey(new Keyframe(sourceKey.time, convertionDelegate(sourceKey.value), sourceKey.inTangent, sourceKey.outTangent, sourceKey.inWeight, sourceKey.outWeight)); - } - } - - static float ConvertFloatNegate(float value) - { - return -value; - } - - static float ConvertFloatMultiply(float value, float multiplier) - { - return value * multiplier; - } - - static void MultiplyCurves(AnimationCurve curve, AnimationCurve curveMultiplier) - { - Keyframe[] keyframes = curve.keys; - for (int i = 0; i < keyframes.Length; i++) - { - keyframes[i].value *= curveMultiplier.Evaluate(keyframes[i].time); - } - curve.keys = keyframes; - } - - static void RemapCurve(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName) - { - AnimationCurve curve; - for (int i = 0; i < clips.Length; i++) - { - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName, out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName, curve); - } - } - } - - static void RemapColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName) - { - AnimationCurve curve; - for (int i = 0; i < clips.Length; i++) - { - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve); - } - - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve); - } - - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve); - } - } - } - } -} +using UnityEngine; +using UnityEditor.AssetImporters; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class AutodeskInteractiveMaterialImport : AssetPostprocessor + { + static readonly uint k_Version = 1; + static readonly int k_Order = 3; + public override uint GetVersion() + { + return k_Version; + } + + public override int GetPostprocessOrder() + { + return k_Order; + } + + public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) + { + var pipelineAsset = GraphicsSettings.currentRenderPipeline; + if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) + return; + + if (IsAutodeskInteractiveMaterial(description)) + { + float floatProperty; + Vector4 vectorProperty; + TexturePropertyDescription textureProperty; + + bool isMasked = description.TryGetProperty("mask_threshold", out floatProperty); + bool isTransparent = description.TryGetProperty("opacity", out floatProperty); + + Shader shader; + if (isMasked) + shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveMaskedShader; + else if (isTransparent) + shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveTransparentShader; + else + shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveShader; + + if (shader == null) + return; + + material.shader = shader; + foreach (var clip in clips) + { + clip.ClearCurves(); + } + + if (description.TryGetProperty("base_color", out vectorProperty)) + material.SetColor("_Color", vectorProperty); + if (description.TryGetProperty("emissive", out vectorProperty)) + material.SetColor("_EmissionColor", vectorProperty); + + if (description.TryGetProperty("roughness", out floatProperty)) + material.SetFloat("_Roughness", floatProperty); + + if (description.TryGetProperty("metallic", out floatProperty)) + material.SetFloat("_Metallic", floatProperty); + + if (description.TryGetProperty("uvTransform", out vectorProperty)) + { + material.SetVector("_UvOffset", new Vector4(vectorProperty.x, vectorProperty.y, .0f, .0f)); + material.SetVector("_UvTiling", new Vector4(vectorProperty.w, vectorProperty.z, .0f, .0f)); + } + + if (description.TryGetProperty("TEX_color_map", out textureProperty)) + { + material.SetTexture("_MainTex", textureProperty.texture); + material.SetFloat("_UseColorMap", 1.0f); + } + else + { + material.SetFloat("_UseColorMap", 0.0f); + } + + if (description.TryGetProperty("TEX_normal_map", out textureProperty)) + { + material.SetTexture("_BumpMap", textureProperty.texture); + material.SetFloat("_UseNormalMap", 1.0f); + } + else + { + material.SetFloat("_UseNormalMap", 0.0f); + } + + if (description.TryGetProperty("TEX_roughness_map", out textureProperty)) + { + material.SetTexture("RoughnessMap", textureProperty.texture); + material.SetFloat("_UseRoughnessMap", 1.0f); + } + else + { + material.SetFloat("_UseRoughnessMap", 0.0f); + } + + if (description.TryGetProperty("TEX_metallic_map", out textureProperty)) + { + material.SetTexture("_MetallicMap", textureProperty.texture); + material.SetFloat("_UseMetallicMap", 1.0f); + } + else + { + material.SetFloat("_UseMetallicMap", 0.0f); + } + + if (description.TryGetProperty("TEX_emissive_map", out textureProperty)) + { + material.SetTexture("_EmissionMap", textureProperty.texture); + material.SetFloat("_UseEmissiveMap", 1.0f); + } + else + { + material.SetFloat("_UseEmissiveMap", 0.0f); + } + + if (description.TryGetProperty("hasTransparencyTexture", out floatProperty)) + material.SetFloat("_UseOpacityMap", floatProperty); + + if (description.TryGetProperty("transparencyMaskThreshold", out floatProperty)) + material.SetFloat("_OpacityThreshold", floatProperty); + + if (description.TryGetProperty("TEX_ao_map", out textureProperty)) + { + var tex = AssetDatabase.LoadAssetAtPath(textureProperty.relativePath); + material.SetTexture("AoMap", tex); + material.SetFloat("UseAoMap", 1.0f); + } + else + { + material.SetFloat("UseAoMap", 0.0f); + } + + RemapColorCurves(description, clips, "base_color", "_Color"); + RemapCurve(description, clips, "mask_threshold", "_Cutoff"); + RemapCurve(description, clips, "metallic", "_Metallic"); + RemapCurve(description, clips, "roughness", "_Glossiness"); + + for (int i = 0; i < clips.Length; i++) + { + if (description.HasAnimationCurveInClip(clips[i].name, "uv_scale.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_scale.y")) + { + AnimationCurve curve; + if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.x", out curve)) + clips[i].SetCurve("", typeof(Material), "_UvTiling.x", curve); + else + clips[i].SetCurve("", typeof(Material), "_UvTiling.x", AnimationCurve.Constant(0.0f, 1.0f, 1.0f)); + + if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.y", out curve)) + clips[i].SetCurve("", typeof(Material), "_UvTiling.y", curve); + else + clips[i].SetCurve("", typeof(Material), "_UvTiling.y", AnimationCurve.Constant(0.0f, 1.0f, 1.0f)); + } + + if (description.HasAnimationCurveInClip(clips[i].name, "uv_offset.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_offset.y")) + { + AnimationCurve curve; + if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.x", out curve)) + clips[i].SetCurve("", typeof(Material), "_UvOffset.x", curve); + else + clips[i].SetCurve("", typeof(Material), "_UvOffset.x", AnimationCurve.Constant(0.0f, 1.0f, 0.0f)); + + if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.y", out curve)) + { + ConvertKeys(curve, ConvertFloatNegate); + clips[i].SetCurve("", typeof(Material), "_UvOffset.y", curve); + } + else + clips[i].SetCurve("", typeof(Material), "_UvOffset.y", AnimationCurve.Constant(0.0f, 1.0f, 0.0f)); + } + } + + if (description.HasAnimationCurve("emissive_intensity")) + { + Vector4 emissiveColor; + description.TryGetProperty("emissive", out emissiveColor); + + for (int i = 0; i < clips.Length; i++) + { + AnimationCurve curve; + description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve); + // remap emissive intensity to emission color + clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve); + } + } + else if (description.TryGetProperty("emissive", out vectorProperty)) + { + if (vectorProperty.x > 0.0f || vectorProperty.y > 0.0f || vectorProperty.z > 0.0f) + { + material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; + material.EnableKeyword("_EMISSION"); + } + + if (description.TryGetProperty("emissive_intensity", out floatProperty)) + { + vectorProperty *= floatProperty; + } + + material.SetColor("_EmissionColor", vectorProperty); + + + if (description.HasAnimationCurve("emissive.x")) + { + if (description.HasAnimationCurve("emissive_intensity")) + { + // combine color and intensity. + for (int i = 0; i < clips.Length; i++) + { + AnimationCurve curve; + AnimationCurve intensityCurve; + description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out intensityCurve); + + description.TryGetAnimationCurve(clips[i].name, "emissive.x", out curve); + MultiplyCurves(curve, intensityCurve); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve); + + description.TryGetAnimationCurve(clips[i].name, "emissive.y", out curve); + MultiplyCurves(curve, intensityCurve); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve); + + description.TryGetAnimationCurve(clips[i].name, "emissive.z", out curve); + MultiplyCurves(curve, intensityCurve); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve); + } + } + else + { + RemapColorCurves(description, clips, "emissive", "_EmissionColor"); + } + } + else if (description.HasAnimationCurve("emissive_intensity")) + { + Vector4 emissiveColor; + description.TryGetProperty("emissive", out emissiveColor); + + for (int i = 0; i < clips.Length; i++) + { + AnimationCurve curve; + description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve); + // remap emissive intensity to emission color + AnimationCurve curveR = new AnimationCurve(); + ConvertAndCopyKeys(curveR, curve, value => ConvertFloatMultiply(emissiveColor.x, value)); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curveR); + + AnimationCurve curveG = new AnimationCurve(); + ConvertAndCopyKeys(curveG, curve, value => ConvertFloatMultiply(emissiveColor.y, value)); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curveG); + + AnimationCurve curveB = new AnimationCurve(); + ConvertAndCopyKeys(curveB, curve, value => ConvertFloatMultiply(emissiveColor.z, value)); + clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curveB); + } + } + } + } + } + + static bool IsAutodeskInteractiveMaterial(MaterialDescription description) + { + return description.TryGetProperty("renderAPI", out string stringValue) && stringValue == "SFX_PBS_SHADER"; + } + + static void ConvertKeys(AnimationCurve curve, System.Func convertionDelegate) + { + Keyframe[] keyframes = curve.keys; + for (int i = 0; i < keyframes.Length; i++) + { + keyframes[i].value = convertionDelegate(keyframes[i].value); + } + curve.keys = keyframes; + } + + static void ConvertAndCopyKeys(AnimationCurve curveDest, AnimationCurve curveSource, System.Func convertionDelegate) + { + for (int i = 0; i < curveSource.keys.Length; i++) + { + var sourceKey = curveSource.keys[i]; + curveDest.AddKey(new Keyframe(sourceKey.time, convertionDelegate(sourceKey.value), sourceKey.inTangent, sourceKey.outTangent, sourceKey.inWeight, sourceKey.outWeight)); + } + } + + static float ConvertFloatNegate(float value) + { + return -value; + } + + static float ConvertFloatMultiply(float value, float multiplier) + { + return value * multiplier; + } + + static void MultiplyCurves(AnimationCurve curve, AnimationCurve curveMultiplier) + { + Keyframe[] keyframes = curve.keys; + for (int i = 0; i < keyframes.Length; i++) + { + keyframes[i].value *= curveMultiplier.Evaluate(keyframes[i].time); + } + curve.keys = keyframes; + } + + static void RemapCurve(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName) + { + AnimationCurve curve; + for (int i = 0; i < clips.Length; i++) + { + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName, out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName, curve); + } + } + } + + static void RemapColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName) + { + AnimationCurve curve; + for (int i = 0; i < clips.Length; i++) + { + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve); + } + + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve); + } + + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve); + } + } + } + } +} diff --git a/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs.meta b/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs.meta index 4a5974a..79ca7f2 100644 --- a/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs.meta +++ b/Editor/AssetPostProcessors/AutodeskInteractiveMaterialImport.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: c127048d39dbf5f4b849798e17e03862 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c127048d39dbf5f4b849798e17e03862 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs b/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs index af9c9bd..281b231 100644 --- a/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs +++ b/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs @@ -1,317 +1,317 @@ -using System.IO; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; -#if UNITY_2020_2_OR_NEWER -using UnityEditor.AssetImporters; -#else -using UnityEditor.Experimental.AssetImporters; -#endif - -namespace UnityEditor.Rendering.Universal -{ - class FBXArnoldSurfaceMaterialDescriptionPreprocessor : AssetPostprocessor - { - static readonly uint k_Version = 2; - static readonly int k_Order = 4; - - static readonly string k_ShaderPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/ArnoldStandardSurface/ArnoldStandardSurface.shadergraph"; - static readonly string k_ShaderTransparentPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/ArnoldStandardSurface/ArnoldStandardSurfaceTransparent.shadergraph"; - - public override uint GetVersion() - { - return k_Version; - } - - public override int GetPostprocessOrder() - { - return k_Order; - } - - static bool IsMayaArnoldStandardSurfaceMaterial(MaterialDescription description) - { - float typeId; - description.TryGetProperty("TypeId", out typeId); - return typeId == 1138001; - } - - static bool Is3DsMaxArnoldStandardSurfaceMaterial(MaterialDescription description) - { - float classIdA; - float classIdB; - description.TryGetProperty("ClassIDa", out classIdA); - description.TryGetProperty("ClassIDb", out classIdB); - return classIdA == 2121471519 && classIdB == 1660373836; - } - - public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, - AnimationClip[] clips) - { - var pipelineAsset = GraphicsSettings.currentRenderPipeline; - if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) - return; - - var lowerCasePath = Path.GetExtension(assetPath).ToLower(); - if (lowerCasePath == ".fbx") - { - if (IsMayaArnoldStandardSurfaceMaterial(description)) - CreateFromMayaArnoldStandardSurfaceMaterial(description, material, clips); - else if (Is3DsMaxArnoldStandardSurfaceMaterial(description)) - CreateFrom3DsMaxArnoldStandardSurfaceMaterial(description, material, clips); - } - } - - void CreateFromMayaArnoldStandardSurfaceMaterial(MaterialDescription description, Material material, - AnimationClip[] clips) - { - float floatProperty; - Vector4 vectorProperty; - TexturePropertyDescription textureProperty; - Shader shader; - - float opacity = 1.0f; - Vector4 opacityColor; - TexturePropertyDescription opacityMap; - description.TryGetProperty("opacity", out opacityColor); - bool hasOpacityMap = description.TryGetProperty("opacity", out opacityMap); - opacity = Mathf.Min(Mathf.Min(opacityColor.x, opacityColor.y), opacityColor.z); - - float transmission; - description.TryGetProperty("transmission", out transmission); - if (opacity == 1.0f && !hasOpacityMap) - { - opacity = 1.0f - transmission; - } - - if (opacity < 1.0f || hasOpacityMap) - { - shader = AssetDatabase.LoadAssetAtPath(k_ShaderTransparentPath); - if (shader == null) - return; - - material.shader = shader; - if (hasOpacityMap) - { - material.SetTexture("_OPACITY_MAP", opacityMap.texture); - material.SetFloat("_OPACITY", 1.0f); - } - else - { - material.SetFloat("_OPACITY", opacity); - } - - } - else - { - shader = AssetDatabase.LoadAssetAtPath(k_ShaderPath); - if (shader == null) - return; - - material.shader = shader; - } - - - foreach (var clip in clips) - { - clip.ClearCurves(); - } - - description.TryGetProperty("base", out floatProperty); - - if (description.TryGetProperty("baseColor", out textureProperty)) - { - SetMaterialTextureProperty("_BASE_COLOR_MAP", material, textureProperty); - material.SetColor("_BASE_COLOR", Color.white * floatProperty); - } - else if (description.TryGetProperty("baseColor", out vectorProperty)) - { - if (QualitySettings.activeColorSpace == ColorSpace.Gamma) - { - vectorProperty.x = Mathf.LinearToGammaSpace(vectorProperty.x); - vectorProperty.y = Mathf.LinearToGammaSpace(vectorProperty.y); - vectorProperty.z = Mathf.LinearToGammaSpace(vectorProperty.z); - vectorProperty *= floatProperty; - } - - material.SetColor("_BASE_COLOR", vectorProperty * floatProperty); - } - - if (description.TryGetProperty("emission", out floatProperty) && floatProperty > 0.0f) - { - remapPropertyColorOrTexture(description, material, "emissionColor", "_EMISSION_COLOR", floatProperty); - } - - remapPropertyFloatOrTexture(description, material, "metalness", "_METALNESS"); - - description.TryGetProperty("specular", out floatProperty); - - remapPropertyColorOrTexture(description, material, "specularColor", "_SPECULAR_COLOR", floatProperty); - remapPropertyFloatOrTexture(description, material, "specularRoughness", "_SPECULAR_ROUGHNESS"); - remapPropertyFloatOrTexture(description, material, "specularIOR", "_SPECULAR_IOR"); - - remapPropertyTexture(description, material, "normalCamera", "_NORMAL_MAP"); - } - - void CreateFrom3DsMaxArnoldStandardSurfaceMaterial(MaterialDescription description, Material material, - AnimationClip[] clips) - { - float floatProperty; - Vector4 vectorProperty; - TexturePropertyDescription textureProperty; - - var shader = AssetDatabase.LoadAssetAtPath(k_ShaderPath); - if (shader == null) - return; - - - material.shader = shader; - foreach (var clip in clips) - { - clip.ClearCurves(); - } - - float opacity = 1.0f; - Vector4 opacityColor; - TexturePropertyDescription opacityMap; - description.TryGetProperty("opacity", out opacityColor); - bool hasOpacityMap = description.TryGetProperty("opacity", out opacityMap); - opacity = Mathf.Min(Mathf.Min(opacityColor.x, opacityColor.y), opacityColor.z); - - if (opacity < 1.0f || hasOpacityMap) - { - if (hasOpacityMap) - { - material.SetTexture("_OPACITY_MAP", opacityMap.texture); - material.SetFloat("_OPACITY", 1.0f); - } - else - { - material.SetFloat("_OPACITY", opacity); - } - } - - description.TryGetProperty("base", out floatProperty); - - if (description.TryGetProperty("base_color.shader", out textureProperty)) - { - SetMaterialTextureProperty("_BASE_COLOR_MAP", material, textureProperty); - material.SetColor("_BASE_COLOR", Color.white * floatProperty); - } - else if (description.TryGetProperty("base_color", out vectorProperty)) - { - if (QualitySettings.activeColorSpace == ColorSpace.Gamma) - { - vectorProperty.x = Mathf.LinearToGammaSpace(vectorProperty.x); - vectorProperty.y = Mathf.LinearToGammaSpace(vectorProperty.y); - vectorProperty.z = Mathf.LinearToGammaSpace(vectorProperty.z); - } - - material.SetColor("_BASE_COLOR", vectorProperty * floatProperty); - } - - if (description.TryGetProperty("emission", out floatProperty) && floatProperty > 0.0f) - { - remapPropertyColorOrTexture3DsMax(description, material, "emission_color", "_EMISSION_COLOR", - floatProperty); - } - - remapPropertyFloatOrTexture3DsMax(description, material, "metalness", "_METALNESS"); - - description.TryGetProperty("specular", out float specularFactor); - - remapPropertyColorOrTexture3DsMax(description, material, "specular_color", "_SPECULAR_COLOR", - specularFactor); - remapPropertyFloatOrTexture3DsMax(description, material, "specular_roughness", "_SPECULAR_ROUGHNESS"); - remapPropertyFloatOrTexture3DsMax(description, material, "specular_IOR", "_SPECULAR_IOR"); - - remapPropertyTexture(description, material, "normal_camera", "_NORMAL_MAP"); - - } - - static void SetMaterialTextureProperty(string propertyName, Material material, - TexturePropertyDescription textureProperty) - { - material.SetTexture(propertyName, textureProperty.texture); - material.SetTextureOffset(propertyName, textureProperty.offset); - material.SetTextureScale(propertyName, textureProperty.scale); - } - - static void remapPropertyFloat(MaterialDescription description, Material material, string inPropName, - string outPropName) - { - if (description.TryGetProperty(inPropName, out float floatProperty)) - { - material.SetFloat(outPropName, floatProperty); - } - } - - static void remapPropertyTexture(MaterialDescription description, Material material, string inPropName, - string outPropName) - { - if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName, textureProperty.texture); - } - } - - static void remapPropertyColorOrTexture3DsMax(MaterialDescription description, Material material, - string inPropName, string outPropName, float multiplier = 1.0f) - { - if (description.TryGetProperty(inPropName + ".shader", out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName + "_MAP", textureProperty.texture); - material.SetColor(outPropName, Color.white * multiplier); - } - else - { - description.TryGetProperty(inPropName, out Vector4 vectorProperty); - material.SetColor(outPropName, vectorProperty * multiplier); - } - } - - static void remapPropertyFloatOrTexture3DsMax(MaterialDescription description, Material material, - string inPropName, string outPropName) - { - if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName + "_MAP", textureProperty.texture); - material.SetFloat(outPropName, 1.0f); - } - else - { - description.TryGetProperty(inPropName, out float floatProperty); - material.SetFloat(outPropName, floatProperty); - } - } - - static void remapPropertyColorOrTexture(MaterialDescription description, Material material, string inPropName, - string outPropName, float multiplier = 1.0f) - { - if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName + "_MAP", textureProperty.texture); - material.SetColor(outPropName, Color.white * multiplier); - } - else - { - description.TryGetProperty(inPropName, out Vector4 vectorProperty); - material.SetColor(outPropName, vectorProperty * multiplier); - } - } - - static void remapPropertyFloatOrTexture(MaterialDescription description, Material material, string inPropName, - string outPropName) - { - if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName + "_MAP", textureProperty.texture); - material.SetFloat(outPropName, 1.0f); - } - else - { - description.TryGetProperty(inPropName, out float floatProperty); - material.SetFloat(outPropName, floatProperty); - } - } - } -} +using System.IO; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; +#if UNITY_2020_2_OR_NEWER +using UnityEditor.AssetImporters; +#else +using UnityEditor.Experimental.AssetImporters; +#endif + +namespace UnityEditor.Rendering.Universal +{ + class FBXArnoldSurfaceMaterialDescriptionPreprocessor : AssetPostprocessor + { + static readonly uint k_Version = 2; + static readonly int k_Order = 4; + + static readonly string k_ShaderPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/ArnoldStandardSurface/ArnoldStandardSurface.shadergraph"; + static readonly string k_ShaderTransparentPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/ArnoldStandardSurface/ArnoldStandardSurfaceTransparent.shadergraph"; + + public override uint GetVersion() + { + return k_Version; + } + + public override int GetPostprocessOrder() + { + return k_Order; + } + + static bool IsMayaArnoldStandardSurfaceMaterial(MaterialDescription description) + { + float typeId; + description.TryGetProperty("TypeId", out typeId); + return typeId == 1138001; + } + + static bool Is3DsMaxArnoldStandardSurfaceMaterial(MaterialDescription description) + { + float classIdA; + float classIdB; + string originalMtl; + description.TryGetProperty("ClassIDa", out classIdA); + description.TryGetProperty("ClassIDb", out classIdB); + description.TryGetProperty("ORIGINAL_MTL", out originalMtl); + return classIdA == 2121471519 && classIdB == 1660373836 && originalMtl != "PHYSICAL_MTL"; + } + + public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, + AnimationClip[] clips) + { + var pipelineAsset = GraphicsSettings.currentRenderPipeline; + if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) + return; + + var lowerCasePath = Path.GetExtension(assetPath).ToLower(); + if (lowerCasePath == ".fbx") + { + if (IsMayaArnoldStandardSurfaceMaterial(description)) + CreateFromMayaArnoldStandardSurfaceMaterial(description, material, clips); + else if (Is3DsMaxArnoldStandardSurfaceMaterial(description)) + CreateFrom3DsMaxArnoldStandardSurfaceMaterial(description, material, clips); + } + } + + void CreateFromMayaArnoldStandardSurfaceMaterial(MaterialDescription description, Material material, + AnimationClip[] clips) + { + float floatProperty; + Vector4 vectorProperty; + TexturePropertyDescription textureProperty; + Shader shader; + + float opacity = 1.0f; + Vector4 opacityColor; + TexturePropertyDescription opacityMap; + description.TryGetProperty("opacity", out opacityColor); + bool hasOpacityMap = description.TryGetProperty("opacity", out opacityMap); + opacity = Mathf.Min(Mathf.Min(opacityColor.x, opacityColor.y), opacityColor.z); + + float transmission; + description.TryGetProperty("transmission", out transmission); + if (opacity == 1.0f && !hasOpacityMap) + { + opacity = 1.0f - transmission; + } + + if (opacity < 1.0f || hasOpacityMap) + { + shader = AssetDatabase.LoadAssetAtPath(k_ShaderTransparentPath); + if (shader == null) + return; + + material.shader = shader; + if (hasOpacityMap) + { + material.SetTexture("_OPACITY_MAP", opacityMap.texture); + material.SetFloat("_OPACITY", 1.0f); + } + else + { + material.SetFloat("_OPACITY", opacity); + } + } + else + { + shader = AssetDatabase.LoadAssetAtPath(k_ShaderPath); + if (shader == null) + return; + + material.shader = shader; + } + + + foreach (var clip in clips) + { + clip.ClearCurves(); + } + + description.TryGetProperty("base", out floatProperty); + + if (description.TryGetProperty("baseColor", out textureProperty)) + { + SetMaterialTextureProperty("_BASE_COLOR_MAP", material, textureProperty); + material.SetColor("_BASE_COLOR", Color.white * floatProperty); + } + else if (description.TryGetProperty("baseColor", out vectorProperty)) + { + if (QualitySettings.activeColorSpace == ColorSpace.Gamma) + { + vectorProperty.x = Mathf.LinearToGammaSpace(vectorProperty.x); + vectorProperty.y = Mathf.LinearToGammaSpace(vectorProperty.y); + vectorProperty.z = Mathf.LinearToGammaSpace(vectorProperty.z); + vectorProperty *= floatProperty; + } + + material.SetColor("_BASE_COLOR", vectorProperty * floatProperty); + } + + if (description.TryGetProperty("emission", out floatProperty) && floatProperty > 0.0f) + { + remapPropertyColorOrTexture(description, material, "emissionColor", "_EMISSION_COLOR", floatProperty); + } + + remapPropertyFloatOrTexture(description, material, "metalness", "_METALNESS"); + + description.TryGetProperty("specular", out floatProperty); + + remapPropertyColorOrTexture(description, material, "specularColor", "_SPECULAR_COLOR", floatProperty); + remapPropertyFloatOrTexture(description, material, "specularRoughness", "_SPECULAR_ROUGHNESS"); + remapPropertyFloatOrTexture(description, material, "specularIOR", "_SPECULAR_IOR"); + + remapPropertyTexture(description, material, "normalCamera", "_NORMAL_MAP"); + } + + void CreateFrom3DsMaxArnoldStandardSurfaceMaterial(MaterialDescription description, Material material, + AnimationClip[] clips) + { + float floatProperty; + Vector4 vectorProperty; + TexturePropertyDescription textureProperty; + + var shader = AssetDatabase.LoadAssetAtPath(k_ShaderPath); + if (shader == null) + return; + + + material.shader = shader; + foreach (var clip in clips) + { + clip.ClearCurves(); + } + + float opacity = 1.0f; + Vector4 opacityColor; + TexturePropertyDescription opacityMap; + description.TryGetProperty("opacity", out opacityColor); + bool hasOpacityMap = description.TryGetProperty("opacity", out opacityMap); + opacity = Mathf.Min(Mathf.Min(opacityColor.x, opacityColor.y), opacityColor.z); + + if (opacity < 1.0f || hasOpacityMap) + { + if (hasOpacityMap) + { + material.SetTexture("_OPACITY_MAP", opacityMap.texture); + material.SetFloat("_OPACITY", 1.0f); + } + else + { + material.SetFloat("_OPACITY", opacity); + } + } + + description.TryGetProperty("base", out floatProperty); + + if (description.TryGetProperty("base_color.shader", out textureProperty)) + { + SetMaterialTextureProperty("_BASE_COLOR_MAP", material, textureProperty); + material.SetColor("_BASE_COLOR", Color.white * floatProperty); + } + else if (description.TryGetProperty("base_color", out vectorProperty)) + { + if (QualitySettings.activeColorSpace == ColorSpace.Gamma) + { + vectorProperty.x = Mathf.LinearToGammaSpace(vectorProperty.x); + vectorProperty.y = Mathf.LinearToGammaSpace(vectorProperty.y); + vectorProperty.z = Mathf.LinearToGammaSpace(vectorProperty.z); + } + + material.SetColor("_BASE_COLOR", vectorProperty * floatProperty); + } + + if (description.TryGetProperty("emission", out floatProperty) && floatProperty > 0.0f) + { + remapPropertyColorOrTexture3DsMax(description, material, "emission_color", "_EMISSION_COLOR", + floatProperty); + } + + remapPropertyFloatOrTexture3DsMax(description, material, "metalness", "_METALNESS"); + + description.TryGetProperty("specular", out float specularFactor); + + remapPropertyColorOrTexture3DsMax(description, material, "specular_color", "_SPECULAR_COLOR", + specularFactor); + remapPropertyFloatOrTexture3DsMax(description, material, "specular_roughness", "_SPECULAR_ROUGHNESS"); + remapPropertyFloatOrTexture3DsMax(description, material, "specular_IOR", "_SPECULAR_IOR"); + + remapPropertyTexture(description, material, "normal_camera", "_NORMAL_MAP"); + } + + static void SetMaterialTextureProperty(string propertyName, Material material, + TexturePropertyDescription textureProperty) + { + material.SetTexture(propertyName, textureProperty.texture); + material.SetTextureOffset(propertyName, textureProperty.offset); + material.SetTextureScale(propertyName, textureProperty.scale); + } + + static void remapPropertyFloat(MaterialDescription description, Material material, string inPropName, + string outPropName) + { + if (description.TryGetProperty(inPropName, out float floatProperty)) + { + material.SetFloat(outPropName, floatProperty); + } + } + + static void remapPropertyTexture(MaterialDescription description, Material material, string inPropName, + string outPropName) + { + if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName, textureProperty.texture); + } + } + + static void remapPropertyColorOrTexture3DsMax(MaterialDescription description, Material material, + string inPropName, string outPropName, float multiplier = 1.0f) + { + if (description.TryGetProperty(inPropName + ".shader", out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName + "_MAP", textureProperty.texture); + material.SetColor(outPropName, Color.white * multiplier); + } + else + { + description.TryGetProperty(inPropName, out Vector4 vectorProperty); + material.SetColor(outPropName, vectorProperty * multiplier); + } + } + + static void remapPropertyFloatOrTexture3DsMax(MaterialDescription description, Material material, + string inPropName, string outPropName) + { + if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName + "_MAP", textureProperty.texture); + material.SetFloat(outPropName, 1.0f); + } + else + { + description.TryGetProperty(inPropName, out float floatProperty); + material.SetFloat(outPropName, floatProperty); + } + } + + static void remapPropertyColorOrTexture(MaterialDescription description, Material material, string inPropName, + string outPropName, float multiplier = 1.0f) + { + if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName + "_MAP", textureProperty.texture); + material.SetColor(outPropName, Color.white * multiplier); + } + else + { + description.TryGetProperty(inPropName, out Vector4 vectorProperty); + material.SetColor(outPropName, vectorProperty * multiplier); + } + } + + static void remapPropertyFloatOrTexture(MaterialDescription description, Material material, string inPropName, + string outPropName) + { + if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName + "_MAP", textureProperty.texture); + material.SetFloat(outPropName, 1.0f); + } + else + { + description.TryGetProperty(inPropName, out float floatProperty); + material.SetFloat(outPropName, floatProperty); + } + } + } +} diff --git a/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs.meta b/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs.meta index 980a5d4..3946374 100644 --- a/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs.meta +++ b/Editor/AssetPostProcessors/FBXArnoldSurfaceMaterialDescriptionPreprocessor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: fa9bd1f1c8ee9a146bdfb156e304bd33 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: fa9bd1f1c8ee9a146bdfb156e304bd33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs b/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs index de0f02e..c7b85e8 100644 --- a/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs +++ b/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs @@ -1,273 +1,275 @@ -using System.IO; -using UnityEditor.AssetImporters; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Rendering.Universal -{ - class FBXMaterialDescriptionPreprocessor : AssetPostprocessor - { - static readonly uint k_Version = 1; - static readonly int k_Order = 2; - public override uint GetVersion() - { - return k_Version; - } - - public override int GetPostprocessOrder() - { - return k_Order; - } - - public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) - { - var pipelineAsset = GraphicsSettings.currentRenderPipeline; - if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) - return; - - var lowerCaseExtension = Path.GetExtension(assetPath).ToLower(); - if (lowerCaseExtension != ".fbx" && lowerCaseExtension != ".obj" && lowerCaseExtension != ".blend" && lowerCaseExtension != ".mb" && lowerCaseExtension != ".ma" && lowerCaseExtension != ".max") - return; - - string path = AssetDatabase.GUIDToAssetPath(ShaderUtils.GetShaderGUID(ShaderPathID.Lit)); - var shader = AssetDatabase.LoadAssetAtPath(path); - if (shader == null) - return; - - - material.shader = shader; - - Vector4 vectorProperty; - float floatProperty; - TexturePropertyDescription textureProperty; - - bool isTransparent = false; - - float opacity; - float transparencyFactor; - if (!description.TryGetProperty("Opacity", out opacity)) - { - if (description.TryGetProperty("TransparencyFactor", out transparencyFactor)) - { - opacity = transparencyFactor == 1.0f ? 1.0f : 1.0f - transparencyFactor; - } - if (opacity == 1.0f && description.TryGetProperty("TransparentColor", out vectorProperty)) - { - opacity = vectorProperty.x == 1.0f ? 1.0f : 1.0f - vectorProperty.x; - } - } - if (opacity < 1.0f || (opacity == 1.0f && description.TryGetProperty("TransparentColor", out textureProperty))) - { - isTransparent = true; - } - else if (description.HasAnimationCurve("TransparencyFactor") || description.HasAnimationCurve("TransparentColor")) - { - isTransparent = true; - } - - if (isTransparent) - { - material.SetInt("_Mode", 3); - material.SetOverrideTag("RenderType", "Transparent"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetInt("_ZWrite", 0); - material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; - material.SetInt("_Surface", 1); - } - else - { - material.SetInt("_Mode", 0); - material.SetOverrideTag("RenderType", ""); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.DisableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = -1; - material.SetInt("_Surface", 0); - } - - if (description.TryGetProperty("DiffuseColor", out textureProperty) && textureProperty.texture!=null) - { - Color diffuseColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); - if (description.TryGetProperty("DiffuseFactor", out floatProperty)) - diffuseColor *= floatProperty; - diffuseColor.a = opacity; - - SetMaterialTextureProperty("_BaseMap", material, textureProperty); - material.SetColor("_BaseColor", diffuseColor); - } - else if (description.TryGetProperty("DiffuseColor", out vectorProperty)) - { - Color diffuseColor = vectorProperty; - diffuseColor.a = opacity; - material.SetColor("_BaseColor", PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor); - } - - if (description.TryGetProperty("Bump", out textureProperty)) - { - SetMaterialTextureProperty("_BumpMap", material, textureProperty); - material.EnableKeyword("_NORMALMAP"); - - if (description.TryGetProperty("BumpFactor", out floatProperty)) - material.SetFloat("_BumpScale", floatProperty); - } - else if (description.TryGetProperty("NormalMap", out textureProperty)) - { - SetMaterialTextureProperty("_BumpMap", material, textureProperty); - material.EnableKeyword("_NORMALMAP"); - - if (description.TryGetProperty("BumpFactor", out floatProperty)) - material.SetFloat("_BumpScale", floatProperty); - } - - if (description.TryGetProperty("EmissiveColor", out textureProperty)) - { - Color emissiveColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); - - material.SetColor("_EmissionColor", emissiveColor); - SetMaterialTextureProperty("_EmissionMap", material, textureProperty); - - if (description.TryGetProperty("EmissiveFactor", out floatProperty) && floatProperty > 0.0f) - { - material.EnableKeyword("_EMISSION"); - material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; - } - } - else if ( - description.TryGetProperty("EmissiveColor", out vectorProperty) && vectorProperty.magnitude > vectorProperty.w - || description.HasAnimationCurve("EmissiveColor.x")) - { - if (description.TryGetProperty("EmissiveFactor", out floatProperty)) - vectorProperty *= floatProperty; - - material.SetColor("_EmissionColor", vectorProperty); - if (floatProperty > 0.0f) - { - material.EnableKeyword("_EMISSION"); - material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; - } - } - - material.SetFloat("_Glossiness", 0.0f); - - if (PlayerSettings.colorSpace == ColorSpace.Linear) - RemapAndTransformColorCurves(description, clips, "DiffuseColor", "_BaseColor", ConvertFloatLinearToGamma); - else - RemapColorCurves(description, clips, "DiffuseColor", "_BaseColor"); - - RemapTransparencyCurves(description, clips); - - RemapColorCurves(description, clips, "EmissiveColor", "_EmissionColor"); - } - - static void RemapTransparencyCurves(MaterialDescription description, AnimationClip[] clips) - { - // For some reason, Opacity is never animated, we have to use TransparencyFactor and TransparentColor - for (int i = 0; i < clips.Length; i++) - { - bool foundTransparencyCurve = false; - AnimationCurve curve; - if (description.TryGetAnimationCurve(clips[i].name, "TransparencyFactor", out curve)) - { - ConvertKeys(curve, ConvertFloatOneMinus); - clips[i].SetCurve("", typeof(Material), "_BaseColor.a", curve); - foundTransparencyCurve = true; - } - else if (description.TryGetAnimationCurve(clips[i].name, "TransparentColor.x", out curve)) - { - ConvertKeys(curve, ConvertFloatOneMinus); - clips[i].SetCurve("", typeof(Material), "_BaseColor.a", curve); - foundTransparencyCurve = true; - } - - if (foundTransparencyCurve && !description.HasAnimationCurveInClip(clips[i].name, "DiffuseColor")) - { - Vector4 diffuseColor; - description.TryGetProperty("DiffuseColor", out diffuseColor); - clips[i].SetCurve("", typeof(Material), "_BaseColor.r", AnimationCurve.Constant(0.0f, 1.0f, diffuseColor.x)); - clips[i].SetCurve("", typeof(Material), "_BaseColor.g", AnimationCurve.Constant(0.0f, 1.0f, diffuseColor.y)); - clips[i].SetCurve("", typeof(Material), "_BaseColor.b", AnimationCurve.Constant(0.0f, 1.0f, diffuseColor.z)); - } - } - } - - static void RemapColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName) - { - AnimationCurve curve; - for (int i = 0; i < clips.Length; i++) - { - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve); - } - - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve); - } - - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve)) - { - clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve); - } - } - } - - static void RemapAndTransformColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName, System.Func converter) - { - AnimationCurve curve; - for (int i = 0; i < clips.Length; i++) - { - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve)) - { - ConvertKeys(curve, converter); - clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve); - } - - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve)) - { - ConvertKeys(curve, converter); - clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve); - } - - if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve)) - { - ConvertKeys(curve, converter); - clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve); - } - } - } - - static float ConvertFloatLinearToGamma(float value) - { - return Mathf.LinearToGammaSpace(value); - } - - static float ConvertFloatOneMinus(float value) - { - return 1.0f - value; - } - - static void ConvertKeys(AnimationCurve curve, System.Func convertionDelegate) - { - Keyframe[] keyframes = curve.keys; - for (int i = 0; i < keyframes.Length; i++) - { - keyframes[i].value = convertionDelegate(keyframes[i].value); - } - curve.keys = keyframes; - } - - static void SetMaterialTextureProperty(string propertyName, Material material, TexturePropertyDescription textureProperty) - { - material.SetTexture(propertyName, textureProperty.texture); - material.SetTextureOffset(propertyName, textureProperty.offset); - material.SetTextureScale(propertyName, textureProperty.scale); - } - } -} +using System.IO; +using UnityEditor.AssetImporters; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class FBXMaterialDescriptionPreprocessor : AssetPostprocessor + { + static readonly uint k_Version = 1; + static readonly int k_Order = 2; + public override uint GetVersion() + { + return k_Version; + } + + public override int GetPostprocessOrder() + { + return k_Order; + } + + public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) + { + var pipelineAsset = GraphicsSettings.currentRenderPipeline; + if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) + return; + + var lowerCaseExtension = Path.GetExtension(assetPath).ToLower(); + if (lowerCaseExtension != ".fbx" && lowerCaseExtension != ".obj" && lowerCaseExtension != ".blend" && lowerCaseExtension != ".mb" && lowerCaseExtension != ".ma" && lowerCaseExtension != ".max") + return; + + string path = AssetDatabase.GUIDToAssetPath(ShaderUtils.GetShaderGUID(ShaderPathID.Lit)); + var shader = AssetDatabase.LoadAssetAtPath(path); + if (shader == null) + return; + + + material.shader = shader; + + Vector4 vectorProperty; + float floatProperty; + TexturePropertyDescription textureProperty; + + bool isTransparent = false; + + float opacity; + float transparencyFactor; + if (!description.TryGetProperty("Opacity", out opacity)) + { + if (description.TryGetProperty("TransparencyFactor", out transparencyFactor)) + { + opacity = transparencyFactor == 1.0f ? 1.0f : 1.0f - transparencyFactor; + } + if (opacity == 1.0f && description.TryGetProperty("TransparentColor", out vectorProperty)) + { + opacity = vectorProperty.x == 1.0f ? 1.0f : 1.0f - vectorProperty.x; + } + } + if (opacity < 1.0f || (opacity == 1.0f && description.TryGetProperty("TransparentColor", out textureProperty))) + { + isTransparent = true; + } + else if (description.HasAnimationCurve("TransparencyFactor") || description.HasAnimationCurve("TransparentColor")) + { + isTransparent = true; + } + + if (isTransparent) + { + material.SetFloat("_Mode", 3.0f); + material.SetOverrideTag("RenderType", "Transparent"); + material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One); + material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetFloat("_ZWrite", 0.0f); + material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; + material.SetFloat("_Surface", 1.0f); + material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + else + { + material.SetFloat("_Mode", 0.0f); + material.SetOverrideTag("RenderType", ""); + material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One); + material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.Zero); + material.SetFloat("_ZWrite", 1.0f); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + material.SetFloat("_Surface", 0.0f); + material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + + if (description.TryGetProperty("DiffuseColor", out textureProperty) && textureProperty.texture != null) + { + Color diffuseColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); + if (description.TryGetProperty("DiffuseFactor", out floatProperty)) + diffuseColor *= floatProperty; + diffuseColor.a = opacity; + + SetMaterialTextureProperty("_BaseMap", material, textureProperty); + material.SetColor("_BaseColor", diffuseColor); + } + else if (description.TryGetProperty("DiffuseColor", out vectorProperty)) + { + Color diffuseColor = vectorProperty; + diffuseColor.a = opacity; + material.SetColor("_BaseColor", PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor); + } + + if (description.TryGetProperty("Bump", out textureProperty)) + { + SetMaterialTextureProperty("_BumpMap", material, textureProperty); + material.EnableKeyword("_NORMALMAP"); + + if (description.TryGetProperty("BumpFactor", out floatProperty)) + material.SetFloat("_BumpScale", floatProperty); + } + else if (description.TryGetProperty("NormalMap", out textureProperty)) + { + SetMaterialTextureProperty("_BumpMap", material, textureProperty); + material.EnableKeyword("_NORMALMAP"); + + if (description.TryGetProperty("BumpFactor", out floatProperty)) + material.SetFloat("_BumpScale", floatProperty); + } + + if (description.TryGetProperty("EmissiveColor", out textureProperty)) + { + Color emissiveColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); + + material.SetColor("_EmissionColor", emissiveColor); + SetMaterialTextureProperty("_EmissionMap", material, textureProperty); + + if (description.TryGetProperty("EmissiveFactor", out floatProperty) && floatProperty > 0.0f) + { + material.EnableKeyword("_EMISSION"); + material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; + } + } + else if ( + description.TryGetProperty("EmissiveColor", out vectorProperty) && vectorProperty.magnitude > vectorProperty.w + || description.HasAnimationCurve("EmissiveColor.x")) + { + if (description.TryGetProperty("EmissiveFactor", out floatProperty)) + vectorProperty *= floatProperty; + + material.SetColor("_EmissionColor", vectorProperty); + if (floatProperty > 0.0f) + { + material.EnableKeyword("_EMISSION"); + material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; + } + } + + material.SetFloat("_Glossiness", 0.0f); + + if (PlayerSettings.colorSpace == ColorSpace.Linear) + RemapAndTransformColorCurves(description, clips, "DiffuseColor", "_BaseColor", ConvertFloatLinearToGamma); + else + RemapColorCurves(description, clips, "DiffuseColor", "_BaseColor"); + + RemapTransparencyCurves(description, clips); + + RemapColorCurves(description, clips, "EmissiveColor", "_EmissionColor"); + } + + static void RemapTransparencyCurves(MaterialDescription description, AnimationClip[] clips) + { + // For some reason, Opacity is never animated, we have to use TransparencyFactor and TransparentColor + for (int i = 0; i < clips.Length; i++) + { + bool foundTransparencyCurve = false; + AnimationCurve curve; + if (description.TryGetAnimationCurve(clips[i].name, "TransparencyFactor", out curve)) + { + ConvertKeys(curve, ConvertFloatOneMinus); + clips[i].SetCurve("", typeof(Material), "_BaseColor.a", curve); + foundTransparencyCurve = true; + } + else if (description.TryGetAnimationCurve(clips[i].name, "TransparentColor.x", out curve)) + { + ConvertKeys(curve, ConvertFloatOneMinus); + clips[i].SetCurve("", typeof(Material), "_BaseColor.a", curve); + foundTransparencyCurve = true; + } + + if (foundTransparencyCurve && !description.HasAnimationCurveInClip(clips[i].name, "DiffuseColor")) + { + Vector4 diffuseColor; + description.TryGetProperty("DiffuseColor", out diffuseColor); + clips[i].SetCurve("", typeof(Material), "_BaseColor.r", AnimationCurve.Constant(0.0f, 1.0f, diffuseColor.x)); + clips[i].SetCurve("", typeof(Material), "_BaseColor.g", AnimationCurve.Constant(0.0f, 1.0f, diffuseColor.y)); + clips[i].SetCurve("", typeof(Material), "_BaseColor.b", AnimationCurve.Constant(0.0f, 1.0f, diffuseColor.z)); + } + } + } + + static void RemapColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName) + { + AnimationCurve curve; + for (int i = 0; i < clips.Length; i++) + { + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve); + } + + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve); + } + + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve)) + { + clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve); + } + } + } + + static void RemapAndTransformColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName, System.Func converter) + { + AnimationCurve curve; + for (int i = 0; i < clips.Length; i++) + { + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve)) + { + ConvertKeys(curve, converter); + clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve); + } + + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve)) + { + ConvertKeys(curve, converter); + clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve); + } + + if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve)) + { + ConvertKeys(curve, converter); + clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve); + } + } + } + + static float ConvertFloatLinearToGamma(float value) + { + return Mathf.LinearToGammaSpace(value); + } + + static float ConvertFloatOneMinus(float value) + { + return 1.0f - value; + } + + static void ConvertKeys(AnimationCurve curve, System.Func convertionDelegate) + { + Keyframe[] keyframes = curve.keys; + for (int i = 0; i < keyframes.Length; i++) + { + keyframes[i].value = convertionDelegate(keyframes[i].value); + } + curve.keys = keyframes; + } + + static void SetMaterialTextureProperty(string propertyName, Material material, TexturePropertyDescription textureProperty) + { + material.SetTexture(propertyName, textureProperty.texture); + material.SetTextureOffset(propertyName, textureProperty.offset); + material.SetTextureScale(propertyName, textureProperty.scale); + } + } +} diff --git a/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs.meta b/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs.meta index 6a6b6af..2d658e7 100644 --- a/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs.meta +++ b/Editor/AssetPostProcessors/FBXMaterialDescriptionPreprocessor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 17ea29e638a319a48b6ec0f98c462d7e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 17ea29e638a319a48b6ec0f98c462d7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/MaterialPostprocessor.cs b/Editor/AssetPostProcessors/MaterialPostprocessor.cs index 7cea250..aeda8e6 100644 --- a/Editor/AssetPostProcessors/MaterialPostprocessor.cs +++ b/Editor/AssetPostProcessors/MaterialPostprocessor.cs @@ -1,393 +1,454 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor.Rendering.Universal.ShaderGUI; -using UnityEngine; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Rendering.Universal -{ - class MaterialModificationProcessor : AssetModificationProcessor - { - static void OnWillCreateAsset(string asset) - { - if (!asset.ToLowerInvariant().EndsWith(".mat")) - { - return; - } - MaterialPostprocessor.s_CreatedAssets.Add(asset); - } - } - - class MaterialReimporter : Editor - { - static bool s_NeedToCheckProjSettingExistence = true; - - static void ReimportAllMaterials() - { - string[] guids = AssetDatabase.FindAssets("t:material", null); - // There can be several materials subAssets per guid ( ie : FBX files ), remove duplicate guids. - var distinctGuids = guids.Distinct(); - - int materialIdx = 0; - int totalMaterials = distinctGuids.Count(); - foreach (var asset in distinctGuids) - { - materialIdx++; - var path = AssetDatabase.GUIDToAssetPath(asset); - EditorUtility.DisplayProgressBar("Material Upgrader re-import", string.Format("({0} of {1}) {2}", materialIdx, totalMaterials, path), (float)materialIdx / (float)totalMaterials); - AssetDatabase.ImportAsset(path); - } - EditorUtility.ClearProgressBar(); - - MaterialPostprocessor.s_NeedsSavingAssets = true; - } - - [InitializeOnLoadMethod] - static void RegisterUpgraderReimport() - { - EditorApplication.update += () => - { - if (Time.renderedFrameCount > 0) - { - bool fileExist = true; - // We check the file existence only once to avoid IO operations every frame. - if (s_NeedToCheckProjSettingExistence) - { - fileExist = System.IO.File.Exists(UniversalProjectSettings.filePath); - s_NeedToCheckProjSettingExistence = false; - } - - //This method is called at opening and when URP package change (update of manifest.json) - var curUpgradeVersion = UniversalProjectSettings.materialVersionForUpgrade; - - if (curUpgradeVersion != MaterialPostprocessor.k_Upgraders.Length) - { - string commandLineOptions = Environment.CommandLine; - bool inTestSuite = commandLineOptions.Contains("-testResults"); - if (!inTestSuite && fileExist) - { - EditorUtility.DisplayDialog("URP Material upgrade", "The Materials in your Project were created using an older version of the Universal Render Pipeline (URP)." + - " Unity must upgrade them to be compatible with your current version of URP. \n" + - " Unity will re-import all of the Materials in your project, save the upgraded Materials to disk, and check them out in source control if needed.\n" + - " Please see the Material upgrade guide in the URP documentation for more information.", "Ok"); - } - - ReimportAllMaterials(); - } - - if (MaterialPostprocessor.s_NeedsSavingAssets) - MaterialPostprocessor.SaveAssetsToDisk(); - } - }; - } - } - - class MaterialPostprocessor : AssetPostprocessor - { - public static List s_CreatedAssets = new List(); - internal static List s_ImportedAssetThatNeedSaving = new List(); - internal static bool s_NeedsSavingAssets = false; - - internal static readonly Action[] k_Upgraders = { UpgradeV1, UpgradeV2, UpgradeV3, UpgradeV4 }; - - static internal void SaveAssetsToDisk() - { - string commandLineOptions = System.Environment.CommandLine; - bool inTestSuite = commandLineOptions.Contains("-testResults"); - if (inTestSuite) - { - // Need to update material version to prevent infinite loop in the upgrader - // when running tests. - UniversalProjectSettings.materialVersionForUpgrade = k_Upgraders.Length; - return; - } - - foreach (var asset in s_ImportedAssetThatNeedSaving) - { - AssetDatabase.MakeEditable(asset); - } - - AssetDatabase.SaveAssets(); - //to prevent data loss, only update the saved version if user applied change and assets are written to - UniversalProjectSettings.materialVersionForUpgrade = k_Upgraders.Length; - UniversalProjectSettings.Save(); - - s_ImportedAssetThatNeedSaving.Clear(); - s_NeedsSavingAssets = false; - } - - static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) - { - var upgradeLog = "UniversalRP Material log:"; - var upgradeCount = 0; - - foreach (var asset in importedAssets) - { - if (!asset.EndsWith(".mat", StringComparison.InvariantCultureIgnoreCase)) - continue; - - var material = (Material)AssetDatabase.LoadAssetAtPath(asset, typeof(Material)); - if (!ShaderUtils.IsLWShader(material.shader)) - continue; - - ShaderPathID id = ShaderUtils.GetEnumFromPath(material.shader.name); - var wasUpgraded = false; - - var debug = "\n" + material.name; - - AssetVersion assetVersion = null; - var allAssets = AssetDatabase.LoadAllAssetsAtPath(asset); - foreach (var subAsset in allAssets) - { - if (subAsset is AssetVersion sub) - { - assetVersion = sub; - } - } - - if (!assetVersion) - { - wasUpgraded = true; - assetVersion = ScriptableObject.CreateInstance(); - if (s_CreatedAssets.Contains(asset)) - { - assetVersion.version = k_Upgraders.Length; - s_CreatedAssets.Remove(asset); - InitializeLatest(material, id); - debug += " initialized."; - } - else - { - assetVersion.version = UniversalProjectSettings.materialVersionForUpgrade; - debug += $" assumed to be version {UniversalProjectSettings.materialVersionForUpgrade} due to missing version."; - } - - assetVersion.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.NotEditable; - AssetDatabase.AddObjectToAsset(assetVersion, asset); - } - - while (assetVersion.version < k_Upgraders.Length) - { - k_Upgraders[assetVersion.version](material, id); - debug += $" upgrading:v{assetVersion.version} to v{assetVersion.version + 1}"; - assetVersion.version++; - wasUpgraded = true; - } - - if (wasUpgraded) - { - upgradeLog += debug; - upgradeCount++; - EditorUtility.SetDirty(assetVersion); - s_ImportedAssetThatNeedSaving.Add(asset); - s_NeedsSavingAssets = true; - } - } - } - - static void InitializeLatest(Material material, ShaderPathID id) - { - - } - - static void UpgradeV1(Material material, ShaderPathID shaderID) - { - var shaderPath = ShaderUtils.GetShaderPath(shaderID); - var upgradeFlag = MaterialUpgrader.UpgradeFlags.LogMessageWhenNoUpgraderFound; - - switch (shaderID) - { - case ShaderPathID.Unlit: - MaterialUpgrader.Upgrade(material, new UnlitUpdaterV1(shaderPath), upgradeFlag); - UnlitShader.SetMaterialKeywords(material); - break; - case ShaderPathID.SimpleLit: - MaterialUpgrader.Upgrade(material, new SimpleLitUpdaterV1(shaderPath), upgradeFlag); - SimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords); - break; - case ShaderPathID.Lit: - MaterialUpgrader.Upgrade(material, new LitUpdaterV1(shaderPath), upgradeFlag); - LitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords); - break; - case ShaderPathID.ParticlesLit: - MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); - ParticlesLitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); - break; - case ShaderPathID.ParticlesSimpleLit: - MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); - ParticlesSimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); - break; - case ShaderPathID.ParticlesUnlit: - MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); - ParticlesUnlitShader.SetMaterialKeywords(material, null, ParticleGUI.SetMaterialKeywords); - break; - } - } - - static void UpgradeV2(Material material, ShaderPathID shaderID) - { - // fix 50 offset on shaders - if(material.HasProperty("_QueueOffset")) - BaseShaderGUI.SetupMaterialBlendMode(material); - } - - static void UpgradeV3(Material material, ShaderPathID shaderID) - { - switch (shaderID) - { - case ShaderPathID.Lit: - case ShaderPathID.SimpleLit: - case ShaderPathID.ParticlesLit: - case ShaderPathID.ParticlesSimpleLit: - case ShaderPathID.ParticlesUnlit: - var propertyID = Shader.PropertyToID("_EmissionColor"); - if (material.HasProperty(propertyID)) - { - // In older version there was a bug that these shaders did not had HDR attribute on emission property. - // This caused emission color to be converted from gamma to linear space. - // In order to avoid visual regression on older projects we will do gamma to linear conversion here. - var emissionGamma = material.GetColor(propertyID); - var emissionLinear = emissionGamma.linear; - material.SetColor(propertyID, emissionLinear); - } - break; - } - } - - static void UpgradeV4(Material material, ShaderPathID shaderID) - {} - } - - // Upgraders v1 - #region UpgradersV1 - - internal class LitUpdaterV1 : MaterialUpgrader - { - public static void UpdateLitDetails(Material material) - { - if (material == null) - throw new ArgumentNullException("material"); - - if(material.GetTexture("_MetallicGlossMap") || material.GetTexture("_SpecGlossMap") || material.GetFloat("_SmoothnessTextureChannel") >= 0.5f) - material.SetFloat("_Smoothness", material.GetFloat("_GlossMapScale")); - else - material.SetFloat("_Smoothness", material.GetFloat("_Glossiness")); - - } - - public LitUpdaterV1(string oldShaderName) - { - if (oldShaderName == null) - throw new ArgumentNullException("oldShaderName"); - - string standardShaderPath = ShaderUtils.GetShaderPath(ShaderPathID.Lit); - - RenameShader(oldShaderName, standardShaderPath, UpdateLitDetails); - - RenameTexture("_MainTex", "_BaseMap"); - RenameColor("_Color", "_BaseColor"); - RenameFloat("_GlossyReflections", "_EnvironmentReflections"); - } - } - - internal class UnlitUpdaterV1 : MaterialUpgrader - { - static Shader bakedLit = Shader.Find(ShaderUtils.GetShaderPath(ShaderPathID.BakedLit)); - - public static void UpgradeToUnlit(Material material) - { - if (material == null) - throw new ArgumentNullException("material"); - - if (material.GetFloat("_SampleGI") != 0) - { - material.shader = bakedLit; - material.EnableKeyword("_NORMALMAP"); - } - } - - public UnlitUpdaterV1(string oldShaderName) - { - if (oldShaderName == null) - throw new ArgumentNullException("oldShaderName"); - - RenameShader(oldShaderName, ShaderUtils.GetShaderPath(ShaderPathID.Unlit), UpgradeToUnlit); - - RenameTexture("_MainTex", "_BaseMap"); - RenameColor("_Color", "_BaseColor"); - } - } - - internal class SimpleLitUpdaterV1 : MaterialUpgrader - { - public SimpleLitUpdaterV1(string oldShaderName) - { - if (oldShaderName == null) - throw new ArgumentNullException("oldShaderName"); - - RenameShader(oldShaderName, ShaderUtils.GetShaderPath(ShaderPathID.SimpleLit), UpgradeToSimpleLit); - - RenameTexture("_MainTex", "_BaseMap"); - RenameColor("_Color", "_BaseColor"); - RenameFloat("_SpecSource", "_SpecularHighlights"); - RenameFloat("_Shininess", "_Smoothness"); - } - - public static void UpgradeToSimpleLit(Material material) - { - if (material == null) - throw new ArgumentNullException("material"); - - var smoothnessSource = 1 - (int)material.GetFloat("_GlossinessSource"); - material.SetFloat("_SmoothnessSource" ,smoothnessSource); - if (material.GetTexture("_SpecGlossMap") == null) - { - var col = material.GetColor("_SpecColor"); - var colBase = material.GetColor("_Color"); - var smoothness = material.GetFloat("_Shininess"); - - if (material.GetFloat("_Surface") == 0) - { - if (smoothnessSource == 1) - colBase.a = smoothness; - else - col.a = smoothness; - material.SetColor("_BaseColor", colBase); - } - - material.SetColor("_BaseColor", colBase); - material.SetColor("_SpecColor", col); - } - } - } - - internal class ParticleUpdaterV1 : MaterialUpgrader - { - public ParticleUpdaterV1(string shaderName) - { - if (shaderName == null) - throw new ArgumentNullException("oldShaderName"); - - RenameShader(shaderName, shaderName, ParticleUpgrader.UpdateSurfaceBlendModes); - - RenameTexture("_MainTex", "_BaseMap"); - RenameColor("_Color", "_BaseColor"); - RenameFloat("_FlipbookMode", "_FlipbookBlending"); - - switch (ShaderUtils.GetEnumFromPath(shaderName)) - { - case ShaderPathID.ParticlesLit: - RenameFloat("_Glossiness", "_Smoothness"); - break; - case ShaderPathID.ParticlesSimpleLit: - RenameFloat("_Glossiness", "_Smoothness"); - break; - case ShaderPathID.ParticlesUnlit: - break; - } - } - } - #endregion -} - +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor.Rendering.Universal.ShaderGUI; +using UnityEditor.ShaderGraph; +using UnityEngine; +using UnityEngine.Rendering.Universal; +using static Unity.Rendering.Universal.ShaderUtils; + +namespace UnityEditor.Rendering.Universal +{ + class MaterialModificationProcessor : AssetModificationProcessor + { + static void OnWillCreateAsset(string asset) + { + if (!asset.ToLowerInvariant().EndsWith(".mat")) + { + return; + } + MaterialPostprocessor.s_CreatedAssets.Add(asset); + } + } + + class MaterialReimporter : Editor + { + static bool s_NeedToCheckProjSettingExistence = true; + + static void ReimportAllMaterials() + { + string[] guids = AssetDatabase.FindAssets("t:material", null); + // There can be several materials subAssets per guid ( ie : FBX files ), remove duplicate guids. + var distinctGuids = guids.Distinct(); + + int materialIdx = 0; + int totalMaterials = distinctGuids.Count(); + + try + { + AssetDatabase.StartAssetEditing(); + + foreach (var asset in distinctGuids) + { + materialIdx++; + var path = AssetDatabase.GUIDToAssetPath(asset); + EditorUtility.DisplayProgressBar("Material Upgrader re-import", string.Format("({0} of {1}) {2}", materialIdx, totalMaterials, path), (float)materialIdx / (float)totalMaterials); + AssetDatabase.ImportAsset(path); + } + } + finally + { + // Ensure the AssetDatabase knows we're finished editing + AssetDatabase.StopAssetEditing(); + } + + EditorUtility.ClearProgressBar(); + + MaterialPostprocessor.s_NeedsSavingAssets = true; + } + + [InitializeOnLoadMethod] + static void RegisterUpgraderReimport() + { + EditorApplication.update += () => + { + if (Time.renderedFrameCount > 0) + { + bool fileExist = true; + // We check the file existence only once to avoid IO operations every frame. + if (s_NeedToCheckProjSettingExistence) + { + fileExist = System.IO.File.Exists(UniversalProjectSettings.filePath); + s_NeedToCheckProjSettingExistence = false; + } + + //This method is called at opening and when URP package change (update of manifest.json) + var curUpgradeVersion = UniversalProjectSettings.materialVersionForUpgrade; + + if (curUpgradeVersion != MaterialPostprocessor.k_Upgraders.Length) + { + string commandLineOptions = Environment.CommandLine; + bool inTestSuite = commandLineOptions.Contains("-testResults"); + if (!inTestSuite && fileExist) + { + EditorUtility.DisplayDialog("URP Material upgrade", "The Materials in your Project were created using an older version of the Universal Render Pipeline (URP)." + + " Unity must upgrade them to be compatible with your current version of URP. \n" + + " Unity will re-import all of the Materials in your project, save the upgraded Materials to disk, and check them out in source control if needed.\n" + + " Please see the Material upgrade guide in the URP documentation for more information.", "Ok"); + } + + ReimportAllMaterials(); + } + + if (MaterialPostprocessor.s_NeedsSavingAssets) + MaterialPostprocessor.SaveAssetsToDisk(); + } + }; + } + } + + class MaterialPostprocessor : AssetPostprocessor + { + public static List s_CreatedAssets = new List(); + internal static List s_ImportedAssetThatNeedSaving = new List(); + internal static bool s_NeedsSavingAssets = false; + + internal static readonly Action[] k_Upgraders = { UpgradeV1, UpgradeV2, UpgradeV3, UpgradeV4, UpgradeV5 }; + + static internal void SaveAssetsToDisk() + { + string commandLineOptions = System.Environment.CommandLine; + bool inTestSuite = commandLineOptions.Contains("-testResults"); + if (inTestSuite) + { + // Need to update material version to prevent infinite loop in the upgrader + // when running tests. + UniversalProjectSettings.materialVersionForUpgrade = k_Upgraders.Length; + return; + } + + foreach (var asset in s_ImportedAssetThatNeedSaving) + { + AssetDatabase.MakeEditable(asset); + } + + AssetDatabase.SaveAssets(); + //to prevent data loss, only update the saved version if user applied change and assets are written to + UniversalProjectSettings.materialVersionForUpgrade = k_Upgraders.Length; + UniversalProjectSettings.Save(); + + s_ImportedAssetThatNeedSaving.Clear(); + s_NeedsSavingAssets = false; + } + + static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) + { + string upgradeLog = ""; + var upgradeCount = 0; + + foreach (var asset in importedAssets) + { + // we only care about materials + if (!asset.EndsWith(".mat", StringComparison.InvariantCultureIgnoreCase)) + continue; + + // load the material and look for it's Universal ShaderID + // we only care about versioning materials using a known Universal ShaderID + // this skips any materials that only target other render pipelines, are user shaders, + // or are shaders we don't care to version + var material = (Material)AssetDatabase.LoadAssetAtPath(asset, typeof(Material)); + var shaderID = GetShaderID(material.shader); + if (shaderID == ShaderID.Unknown) + continue; + + var wasUpgraded = false; + var debug = "\n" + material.name + "(" + shaderID + ")"; + + // look for the Universal AssetVersion + AssetVersion assetVersion = null; + var allAssets = AssetDatabase.LoadAllAssetsAtPath(asset); + foreach (var subAsset in allAssets) + { + if (subAsset is AssetVersion sub) + { + assetVersion = sub; + } + } + + if (!assetVersion) + { + wasUpgraded = true; + assetVersion = ScriptableObject.CreateInstance(); + if (s_CreatedAssets.Contains(asset)) + { + assetVersion.version = k_Upgraders.Length; + s_CreatedAssets.Remove(asset); + InitializeLatest(material, shaderID); + debug += " initialized."; + } + else + { + if (shaderID.IsShaderGraph()) + { + // ShaderGraph materials NEVER had asset versioning applied prior to version 5. + // so if we see a ShaderGraph material with no assetVersion, set it to 5 to ensure we apply all necessary versions. + assetVersion.version = 5; + debug += $" shadergraph material assumed to be version 5 due to missing version."; + } + else + { + assetVersion.version = UniversalProjectSettings.materialVersionForUpgrade; + debug += $" assumed to be version {UniversalProjectSettings.materialVersionForUpgrade} due to missing version."; + } + } + + assetVersion.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.NotEditable; + AssetDatabase.AddObjectToAsset(assetVersion, asset); + } + + while (assetVersion.version < k_Upgraders.Length) + { + k_Upgraders[assetVersion.version](material, shaderID); + debug += $" upgrading:v{assetVersion.version} to v{assetVersion.version + 1}"; + assetVersion.version++; + wasUpgraded = true; + } + + if (wasUpgraded) + { + upgradeLog += debug; + upgradeCount++; + EditorUtility.SetDirty(assetVersion); + s_ImportedAssetThatNeedSaving.Add(asset); + s_NeedsSavingAssets = true; + } + } + + // Uncomment to show upgrade debug logs + //if (!string.IsNullOrEmpty(upgradeLog)) + // Debug.Log("UniversalRP Material log: " + upgradeLog); + } + + static void InitializeLatest(Material material, ShaderID id) + { + // newly created materials should reset their keywords immediately (in case inspector doesn't get invoked) + Unity.Rendering.Universal.ShaderUtils.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial, id); + } + + static void UpgradeV1(Material material, ShaderID shaderID) + { + if (shaderID.IsShaderGraph()) + return; + + var shaderPath = ShaderUtils.GetShaderPath((ShaderPathID)shaderID); + var upgradeFlag = MaterialUpgrader.UpgradeFlags.LogMessageWhenNoUpgraderFound; + + switch (shaderID) + { + case ShaderID.Unlit: + MaterialUpgrader.Upgrade(material, new UnlitUpdaterV1(shaderPath), upgradeFlag); + UnlitShader.SetMaterialKeywords(material); + break; + case ShaderID.SimpleLit: + MaterialUpgrader.Upgrade(material, new SimpleLitUpdaterV1(shaderPath), upgradeFlag); + SimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords); + break; + case ShaderID.Lit: + MaterialUpgrader.Upgrade(material, new LitUpdaterV1(shaderPath), upgradeFlag); + LitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords); + break; + case ShaderID.ParticlesLit: + MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); + ParticlesLitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); + break; + case ShaderID.ParticlesSimpleLit: + MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); + ParticlesSimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); + break; + case ShaderID.ParticlesUnlit: + MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); + ParticlesUnlitShader.SetMaterialKeywords(material, null, ParticleGUI.SetMaterialKeywords); + break; + } + } + + static void UpgradeV2(Material material, ShaderID shaderID) + { + if (shaderID.IsShaderGraph()) + return; + + // fix 50 offset on shaders + if (material.HasProperty("_QueueOffset")) + BaseShaderGUI.SetupMaterialBlendMode(material); + } + + static void UpgradeV3(Material material, ShaderID shaderID) + { + if (shaderID.IsShaderGraph()) + return; + + switch (shaderID) + { + case ShaderID.Lit: + case ShaderID.SimpleLit: + case ShaderID.ParticlesLit: + case ShaderID.ParticlesSimpleLit: + case ShaderID.ParticlesUnlit: + var propertyID = Shader.PropertyToID("_EmissionColor"); + if (material.HasProperty(propertyID)) + { + // In older version there was a bug that these shaders did not had HDR attribute on emission property. + // This caused emission color to be converted from gamma to linear space. + // In order to avoid visual regression on older projects we will do gamma to linear conversion here. + var emissionGamma = material.GetColor(propertyID); + var emissionLinear = emissionGamma.linear; + material.SetColor(propertyID, emissionLinear); + } + break; + } + } + + static void UpgradeV4(Material material, ShaderID shaderID) + { } + + static void UpgradeV5(Material material, ShaderID shaderID) + { + if (shaderID.IsShaderGraph()) + return; + + var propertyID = Shader.PropertyToID("_Surface"); + if (material.HasProperty(propertyID)) + { + float surfaceType = material.GetFloat(propertyID); + if (surfaceType >= 1.0f) + { + material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + else + { + material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + } + } + } + + // Upgraders v1 + #region UpgradersV1 + + internal class LitUpdaterV1 : MaterialUpgrader + { + public static void UpdateLitDetails(Material material) + { + if (material == null) + throw new ArgumentNullException("material"); + + if (material.GetTexture("_MetallicGlossMap") || material.GetTexture("_SpecGlossMap") || material.GetFloat("_SmoothnessTextureChannel") >= 0.5f) + material.SetFloat("_Smoothness", material.GetFloat("_GlossMapScale")); + else + material.SetFloat("_Smoothness", material.GetFloat("_Glossiness")); + } + + public LitUpdaterV1(string oldShaderName) + { + if (oldShaderName == null) + throw new ArgumentNullException("oldShaderName"); + + string standardShaderPath = ShaderUtils.GetShaderPath(ShaderPathID.Lit); + + RenameShader(oldShaderName, standardShaderPath, UpdateLitDetails); + + RenameTexture("_MainTex", "_BaseMap"); + RenameColor("_Color", "_BaseColor"); + RenameFloat("_GlossyReflections", "_EnvironmentReflections"); + } + } + + internal class UnlitUpdaterV1 : MaterialUpgrader + { + static Shader bakedLit = Shader.Find(ShaderUtils.GetShaderPath(ShaderPathID.BakedLit)); + + public static void UpgradeToUnlit(Material material) + { + if (material == null) + throw new ArgumentNullException("material"); + + if (material.GetFloat("_SampleGI") != 0) + { + material.shader = bakedLit; + material.EnableKeyword("_NORMALMAP"); + } + } + + public UnlitUpdaterV1(string oldShaderName) + { + if (oldShaderName == null) + throw new ArgumentNullException("oldShaderName"); + + RenameShader(oldShaderName, ShaderUtils.GetShaderPath(ShaderPathID.Unlit), UpgradeToUnlit); + + RenameTexture("_MainTex", "_BaseMap"); + RenameColor("_Color", "_BaseColor"); + } + } + + internal class SimpleLitUpdaterV1 : MaterialUpgrader + { + public SimpleLitUpdaterV1(string oldShaderName) + { + if (oldShaderName == null) + throw new ArgumentNullException("oldShaderName"); + + RenameShader(oldShaderName, ShaderUtils.GetShaderPath(ShaderPathID.SimpleLit), UpgradeToSimpleLit); + + RenameTexture("_MainTex", "_BaseMap"); + RenameColor("_Color", "_BaseColor"); + RenameFloat("_SpecSource", "_SpecularHighlights"); + RenameFloat("_Shininess", "_Smoothness"); + } + + public static void UpgradeToSimpleLit(Material material) + { + if (material == null) + throw new ArgumentNullException("material"); + + var smoothnessSource = 1 - (int)material.GetFloat("_GlossinessSource"); + material.SetFloat("_SmoothnessSource", smoothnessSource); + if (material.GetTexture("_SpecGlossMap") == null) + { + var col = material.GetColor("_SpecColor"); + var colBase = material.GetColor("_Color"); + var smoothness = material.GetFloat("_Shininess"); + + if (material.GetFloat("_Surface") == 0) + { + if (smoothnessSource == 1) + colBase.a = smoothness; + else + col.a = smoothness; + material.SetColor("_BaseColor", colBase); + } + + material.SetColor("_BaseColor", colBase); + material.SetColor("_SpecColor", col); + } + } + } + + internal class ParticleUpdaterV1 : MaterialUpgrader + { + public ParticleUpdaterV1(string shaderName) + { + if (shaderName == null) + throw new ArgumentNullException("oldShaderName"); + + RenameShader(shaderName, shaderName, ParticleUpgrader.UpdateSurfaceBlendModes); + + RenameTexture("_MainTex", "_BaseMap"); + RenameColor("_Color", "_BaseColor"); + RenameFloat("_FlipbookMode", "_FlipbookBlending"); + + switch (ShaderUtils.GetEnumFromPath(shaderName)) + { + case ShaderPathID.ParticlesLit: + RenameFloat("_Glossiness", "_Smoothness"); + break; + case ShaderPathID.ParticlesSimpleLit: + RenameFloat("_Glossiness", "_Smoothness"); + break; + case ShaderPathID.ParticlesUnlit: + break; + } + } + } + #endregion +} diff --git a/Editor/AssetPostProcessors/MaterialPostprocessor.cs.meta b/Editor/AssetPostProcessors/MaterialPostprocessor.cs.meta index eb92cc9..317470e 100644 --- a/Editor/AssetPostProcessors/MaterialPostprocessor.cs.meta +++ b/Editor/AssetPostProcessors/MaterialPostprocessor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 5d970c86e29d2c5438cc8c146e9805cd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 5d970c86e29d2c5438cc8c146e9805cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/ModelPostProcessor.cs b/Editor/AssetPostProcessors/ModelPostProcessor.cs new file mode 100644 index 0000000..8ff523b --- /dev/null +++ b/Editor/AssetPostProcessors/ModelPostProcessor.cs @@ -0,0 +1,15 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class ModelPostprocessor : AssetPostprocessor + { + void OnPostprocessModel(GameObject go) + { + CoreEditorUtils.AddAdditionalData(go); + CoreEditorUtils.AddAdditionalData(go); + } + } +} diff --git a/Editor/AssetPostProcessors/ModelPostProcessor.cs.meta b/Editor/AssetPostProcessors/ModelPostProcessor.cs.meta new file mode 100644 index 0000000..9a1fe7c --- /dev/null +++ b/Editor/AssetPostProcessors/ModelPostProcessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c22659d508770e94b9278d8f089e40b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs b/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs index 822497f..e535f21 100644 --- a/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs +++ b/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs @@ -1,305 +1,307 @@ -using UnityEditor.Experimental; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; -#if UNITY_2020_2_OR_NEWER -using UnityEditor.AssetImporters; -#else -using UnityEditor.Experimental.AssetImporters; -#endif - -namespace UnityEditor.Rendering.Universal -{ - class PhysicalMaterial3DsMaxPreprocessor : AssetPostprocessor - { - static readonly uint k_Version = 1; - static readonly int k_Order = 4; - static readonly string k_ShaderPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/PhysicalMaterial3DsMax/PhysicalMaterial3DsMax.ShaderGraph"; - static readonly string k_ShaderTransparentPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/PhysicalMaterial3DsMax/PhysicalMaterial3DsMaxTransparent.ShaderGraph"; - - public override uint GetVersion() - { - return k_Version; - } - - public override int GetPostprocessOrder() - { - return k_Order; - } - - static bool Is3DsMaxPhysicalMaterial(MaterialDescription description) - { - float classIdA; - float classIdB; - description.TryGetProperty("ClassIDa", out classIdA); - description.TryGetProperty("ClassIDb", out classIdB); - return classIdA == 1030429932 && classIdB == -559038463; - } - - static bool Is3DsMaxSimplifiedPhysicalMaterial(MaterialDescription description) - { - float classIdA; - float classIdB; - float useGlossiness; - description.TryGetProperty("ClassIDa", out classIdA); - description.TryGetProperty("ClassIDb", out classIdB); - description.TryGetProperty("useGlossiness", out useGlossiness); - - return classIdA == -804315648 && classIdB == -1099438848 && useGlossiness == 2.0f; - } - - public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) - { - var pipelineAsset = GraphicsSettings.currentRenderPipeline; - if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) - return; - - if (Is3DsMaxPhysicalMaterial(description)) - { - CreateFrom3DsPhysicalMaterial(description, material, clips); - } - else if (Is3DsMaxSimplifiedPhysicalMaterial(description)) - { - CreateFrom3DsSimplifiedPhysicalMaterial(description, material, clips); - } - } - - void CreateFrom3DsSimplifiedPhysicalMaterial(MaterialDescription description, Material material, AnimationClip[] clips) - { - float floatProperty; - Vector4 vectorProperty; - TexturePropertyDescription textureProperty; - - description.TryGetProperty("basecolor", out vectorProperty); - bool hasTransparencyScalar = vectorProperty.w !=1.0f; - var hasTransparencyMap = description.TryGetProperty("opacity_map", out textureProperty); - bool isTransparent = hasTransparencyMap | hasTransparencyScalar; - - - Shader shader; - if (isTransparent) - shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveTransparentShader; - else - shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveShader; - - if (shader == null) - return; - - material.shader = shader; - foreach (var clip in clips) - { - clip.ClearCurves(); - } - - if (hasTransparencyMap) - { - material.SetFloat("_UseOpacityMap", 1.0f); - material.SetTexture("_OpacityMap", textureProperty.texture); - } - else if (hasTransparencyScalar) - { - material.SetFloat("_Opacity", vectorProperty.w); - } - - if (description.TryGetProperty("basecolor", out vectorProperty)) - material.SetColor("_Color", vectorProperty); - - if (description.TryGetProperty("emit_color", out vectorProperty)) - material.SetColor("_EmissionColor", vectorProperty); - - if (description.TryGetProperty("roughness", out floatProperty)) - material.SetFloat("_Glossiness", floatProperty); - - if (description.TryGetProperty("metalness", out floatProperty)) - material.SetFloat("_Metallic", floatProperty); - - if (description.TryGetProperty("base_color_map", out textureProperty)) - { - material.SetTexture("_MainTex", textureProperty.texture); - material.SetFloat("_UseColorMap", 1.0f); - material.SetColor("_UvTiling", new Vector4(textureProperty.scale.x, textureProperty.scale.y, 0.0f, 0.0f)); - material.SetColor("_UvOffset", new Vector4(textureProperty.offset.x, textureProperty.offset.y, 0.0f, 0.0f)); - } - else - { - material.SetFloat("_UseColorMap", 0.0f); - } - - if (description.TryGetProperty("norm_map", out textureProperty)) - { - material.SetTexture("_BumpMap", textureProperty.texture); - material.SetFloat("_UseNormalMap", 1.0f); - } - else - { - material.SetFloat("_UseNormalMap", 0.0f); - } - - if (description.TryGetProperty("roughness_map", out textureProperty)) - { - material.SetTexture("_SpecGlossMap", textureProperty.texture); - material.SetFloat("_UseRoughnessMap", 1.0f); - } - else - { - material.SetFloat("_UseRoughnessMap", 0.0f); - } - - if (description.TryGetProperty("metalness_map", out textureProperty)) - { - material.SetTexture("_MetallicGlossMap", textureProperty.texture); - material.SetFloat("_UseMetallicMap", 1.0f); - } - else - { - material.SetFloat("_UseMetallicMap", 0.0f); - } - - if (description.TryGetProperty("emit_color_map", out textureProperty)) - { - material.SetTexture("_EmissionMap", textureProperty.texture); - material.SetFloat("_UseEmissiveMap", 1.0f); - } - else - { - material.SetFloat("_UseEmissiveMap", 0.0f); - } - - if (description.TryGetProperty("ao_map", out textureProperty)) - { - var tex = AssetDatabase.LoadAssetAtPath(textureProperty.relativePath); - material.SetTexture("AoMap", tex); - material.SetFloat("UseAoMap", 1.0f); - } - else - { - material.SetFloat("UseAoMap", 0.0f); - } - } - - void CreateFrom3DsPhysicalMaterial(MaterialDescription description, Material material, AnimationClip[] clips) - { - float floatProperty; - Vector4 vectorProperty; - TexturePropertyDescription textureProperty; - Shader shader; - - description.TryGetProperty("transparency", out floatProperty); - bool hasTransparencyMap = - description.TryGetProperty("transparency_map", out textureProperty); - - if (floatProperty > 0.0f || hasTransparencyMap) - { - shader = AssetDatabase.LoadAssetAtPath(k_ShaderTransparentPath); - if (shader == null) - return; - - material.shader = shader; - if (hasTransparencyMap) - { - material.SetTexture("_TRANSPARENCY_MAP", textureProperty.texture); - material.SetFloat("_TRANSPARENCY", 1.0f); - } - else - { - material.SetFloat("_TRANSPARENCY", floatProperty); - } - } - else - { - shader = AssetDatabase.LoadAssetAtPath(k_ShaderPath); - if (shader == null) - return; - - material.shader = shader; - } - - foreach (var clip in clips) - { - clip.ClearCurves(); - } - - RemapPropertyFloat(description, material, "base_weight", "_BASE_COLOR_WEIGHT"); - if (description.TryGetProperty("base_color_map", out textureProperty)) - { - SetMaterialTextureProperty("_BASE_COLOR_MAP", material, textureProperty); - } - else if (description.TryGetProperty("base_color", out vectorProperty)) - { - if (QualitySettings.activeColorSpace == ColorSpace.Gamma) - { - vectorProperty.x = Mathf.LinearToGammaSpace(vectorProperty.x); - vectorProperty.y = Mathf.LinearToGammaSpace(vectorProperty.y); - vectorProperty.z = Mathf.LinearToGammaSpace(vectorProperty.z); - vectorProperty.w = Mathf.LinearToGammaSpace(vectorProperty.w); - } - material.SetColor("_BASE_COLOR", vectorProperty); - } - - RemapPropertyFloat(description, material, "reflectivity", "_REFLECTIONS_WEIGHT"); - RemapPropertyTextureOrColor(description, material, "refl_color", "_REFLECTIONS_COLOR"); - RemapPropertyTextureOrFloat(description, material, "metalness", "_METALNESS"); - RemapPropertyTextureOrFloat(description, material, "roughness", "_REFLECTIONS_ROUGHNESS"); - RemapPropertyTextureOrFloat(description, material, "trans_ior", "_REFLECTIONS_IOR"); - RemapPropertyFloat(description, material, "emission", "_EMISSION_WEIGHT"); - RemapPropertyTextureOrColor(description, material, "emit_color", "_EMISSION_COLOR"); - - RemapPropertyFloat(description, material, "bump_map_amt", "_BUMP_MAP_STRENGTH"); - RemapPropertyTexture(description, material, "bump_map", "_BUMP_MAP"); - } - - static void SetMaterialTextureProperty(string propertyName, Material material, - TexturePropertyDescription textureProperty) - { - material.SetTexture(propertyName, textureProperty.texture); - material.SetTextureOffset(propertyName, textureProperty.offset); - material.SetTextureScale(propertyName, textureProperty.scale); - } - - static void RemapPropertyFloat(MaterialDescription description, Material material, string inPropName, - string outPropName) - { - if (description.TryGetProperty(inPropName, out float floatProperty)) - { - material.SetFloat(outPropName, floatProperty); - } - } - - static void RemapPropertyTexture(MaterialDescription description, Material material, string inPropName, - string outPropName) - { - if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName, textureProperty.texture); - } - } - - static void RemapPropertyTextureOrColor(MaterialDescription description, Material material, - string inPropName, string outPropName) - { - if (description.TryGetProperty(inPropName + "_map", out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName + "_MAP", textureProperty.texture); - material.SetColor(outPropName, Color.white); - } - else if(description.TryGetProperty(inPropName, out Vector4 color)) - { - material.SetColor(outPropName, color); - } - } - - static void RemapPropertyTextureOrFloat(MaterialDescription description, Material material, - string inPropName, string outPropName) - { - if (description.TryGetProperty(inPropName + "_map", out TexturePropertyDescription textureProperty)) - { - material.SetTexture(outPropName + "_MAP", textureProperty.texture); - material.SetFloat(outPropName, 1.0f); - } - else if(description.TryGetProperty(inPropName, out float floatProperty)) - { - material.SetFloat(outPropName, floatProperty); - } - } - } -} +using UnityEditor.Experimental; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; +#if UNITY_2020_2_OR_NEWER +using UnityEditor.AssetImporters; +#else +using UnityEditor.Experimental.AssetImporters; +#endif + +namespace UnityEditor.Rendering.Universal +{ + class PhysicalMaterial3DsMaxPreprocessor : AssetPostprocessor + { + static readonly uint k_Version = 1; + static readonly int k_Order = 4; + static readonly string k_ShaderPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/PhysicalMaterial3DsMax/PhysicalMaterial3DsMax.shadergraph"; + static readonly string k_ShaderTransparentPath = "Packages/com.unity.render-pipelines.universal/Runtime/Materials/PhysicalMaterial3DsMax/PhysicalMaterial3DsMaxTransparent.shadergraph"; + + public override uint GetVersion() + { + return k_Version; + } + + public override int GetPostprocessOrder() + { + return k_Order; + } + + static bool Is3DsMaxPhysicalMaterial(MaterialDescription description) + { + float classIdA; + float classIdB; + string originalMtl; + description.TryGetProperty("ClassIDa", out classIdA); + description.TryGetProperty("ClassIDb", out classIdB); + description.TryGetProperty("ORIGINAL_MTL", out originalMtl); + return classIdA == 1030429932 && classIdB == -559038463 || originalMtl == "PHYSICAL_MTL"; + } + + static bool Is3DsMaxSimplifiedPhysicalMaterial(MaterialDescription description) + { + float classIdA; + float classIdB; + float useGlossiness; + description.TryGetProperty("ClassIDa", out classIdA); + description.TryGetProperty("ClassIDb", out classIdB); + description.TryGetProperty("useGlossiness", out useGlossiness); + + return classIdA == -804315648 && classIdB == -1099438848 && useGlossiness == 2.0f; + } + + public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) + { + var pipelineAsset = GraphicsSettings.currentRenderPipeline; + if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) + return; + + if (Is3DsMaxPhysicalMaterial(description)) + { + CreateFrom3DsPhysicalMaterial(description, material, clips); + } + else if (Is3DsMaxSimplifiedPhysicalMaterial(description)) + { + CreateFrom3DsSimplifiedPhysicalMaterial(description, material, clips); + } + } + + void CreateFrom3DsSimplifiedPhysicalMaterial(MaterialDescription description, Material material, AnimationClip[] clips) + { + float floatProperty; + Vector4 vectorProperty; + TexturePropertyDescription textureProperty; + + description.TryGetProperty("basecolor", out vectorProperty); + bool hasTransparencyScalar = vectorProperty.w != 1.0f; + var hasTransparencyMap = description.TryGetProperty("opacity_map", out textureProperty); + bool isTransparent = hasTransparencyMap | hasTransparencyScalar; + + + Shader shader; + if (isTransparent) + shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveTransparentShader; + else + shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveShader; + + if (shader == null) + return; + + material.shader = shader; + foreach (var clip in clips) + { + clip.ClearCurves(); + } + + if (hasTransparencyMap) + { + material.SetFloat("_UseOpacityMap", 1.0f); + material.SetTexture("_OpacityMap", textureProperty.texture); + } + else if (hasTransparencyScalar) + { + material.SetFloat("_Opacity", vectorProperty.w); + } + + if (description.TryGetProperty("basecolor", out vectorProperty)) + material.SetColor("_Color", vectorProperty); + + if (description.TryGetProperty("emit_color", out vectorProperty)) + material.SetColor("_EmissionColor", vectorProperty); + + if (description.TryGetProperty("roughness", out floatProperty)) + material.SetFloat("_Glossiness", floatProperty); + + if (description.TryGetProperty("metalness", out floatProperty)) + material.SetFloat("_Metallic", floatProperty); + + if (description.TryGetProperty("base_color_map", out textureProperty)) + { + material.SetTexture("_MainTex", textureProperty.texture); + material.SetFloat("_UseColorMap", 1.0f); + material.SetColor("_UvTiling", new Vector4(textureProperty.scale.x, textureProperty.scale.y, 0.0f, 0.0f)); + material.SetColor("_UvOffset", new Vector4(textureProperty.offset.x, textureProperty.offset.y, 0.0f, 0.0f)); + } + else + { + material.SetFloat("_UseColorMap", 0.0f); + } + + if (description.TryGetProperty("norm_map", out textureProperty)) + { + material.SetTexture("_BumpMap", textureProperty.texture); + material.SetFloat("_UseNormalMap", 1.0f); + } + else + { + material.SetFloat("_UseNormalMap", 0.0f); + } + + if (description.TryGetProperty("roughness_map", out textureProperty)) + { + material.SetTexture("_SpecGlossMap", textureProperty.texture); + material.SetFloat("_UseRoughnessMap", 1.0f); + } + else + { + material.SetFloat("_UseRoughnessMap", 0.0f); + } + + if (description.TryGetProperty("metalness_map", out textureProperty)) + { + material.SetTexture("_MetallicGlossMap", textureProperty.texture); + material.SetFloat("_UseMetallicMap", 1.0f); + } + else + { + material.SetFloat("_UseMetallicMap", 0.0f); + } + + if (description.TryGetProperty("emit_color_map", out textureProperty)) + { + material.SetTexture("_EmissionMap", textureProperty.texture); + material.SetFloat("_UseEmissiveMap", 1.0f); + } + else + { + material.SetFloat("_UseEmissiveMap", 0.0f); + } + + if (description.TryGetProperty("ao_map", out textureProperty)) + { + var tex = AssetDatabase.LoadAssetAtPath(textureProperty.relativePath); + material.SetTexture("AoMap", tex); + material.SetFloat("UseAoMap", 1.0f); + } + else + { + material.SetFloat("UseAoMap", 0.0f); + } + } + + void CreateFrom3DsPhysicalMaterial(MaterialDescription description, Material material, AnimationClip[] clips) + { + float floatProperty; + Vector4 vectorProperty; + TexturePropertyDescription textureProperty; + Shader shader; + + description.TryGetProperty("transparency", out floatProperty); + bool hasTransparencyMap = + description.TryGetProperty("transparency_map", out textureProperty); + + if (floatProperty > 0.0f || hasTransparencyMap) + { + shader = AssetDatabase.LoadAssetAtPath(k_ShaderTransparentPath); + if (shader == null) + return; + + material.shader = shader; + if (hasTransparencyMap) + { + material.SetTexture("_TRANSPARENCY_MAP", textureProperty.texture); + material.SetFloat("_TRANSPARENCY", 1.0f); + } + else + { + material.SetFloat("_TRANSPARENCY", floatProperty); + } + } + else + { + shader = AssetDatabase.LoadAssetAtPath(k_ShaderPath); + if (shader == null) + return; + + material.shader = shader; + } + + foreach (var clip in clips) + { + clip.ClearCurves(); + } + + RemapPropertyFloat(description, material, "base_weight", "_BASE_COLOR_WEIGHT"); + if (description.TryGetProperty("base_color_map", out textureProperty)) + { + SetMaterialTextureProperty("_BASE_COLOR_MAP", material, textureProperty); + } + else if (description.TryGetProperty("base_color", out vectorProperty)) + { + if (QualitySettings.activeColorSpace == ColorSpace.Gamma) + { + vectorProperty.x = Mathf.LinearToGammaSpace(vectorProperty.x); + vectorProperty.y = Mathf.LinearToGammaSpace(vectorProperty.y); + vectorProperty.z = Mathf.LinearToGammaSpace(vectorProperty.z); + vectorProperty.w = Mathf.LinearToGammaSpace(vectorProperty.w); + } + material.SetColor("_BASE_COLOR", vectorProperty); + } + + RemapPropertyFloat(description, material, "reflectivity", "_REFLECTIONS_WEIGHT"); + RemapPropertyTextureOrColor(description, material, "refl_color", "_REFLECTIONS_COLOR"); + RemapPropertyTextureOrFloat(description, material, "metalness", "_METALNESS"); + RemapPropertyTextureOrFloat(description, material, "roughness", "_REFLECTIONS_ROUGHNESS"); + RemapPropertyTextureOrFloat(description, material, "trans_ior", "_REFLECTIONS_IOR"); + RemapPropertyFloat(description, material, "emission", "_EMISSION_WEIGHT"); + RemapPropertyTextureOrColor(description, material, "emit_color", "_EMISSION_COLOR"); + + RemapPropertyFloat(description, material, "bump_map_amt", "_BUMP_MAP_STRENGTH"); + RemapPropertyTexture(description, material, "bump_map", "_BUMP_MAP"); + } + + static void SetMaterialTextureProperty(string propertyName, Material material, + TexturePropertyDescription textureProperty) + { + material.SetTexture(propertyName, textureProperty.texture); + material.SetTextureOffset(propertyName, textureProperty.offset); + material.SetTextureScale(propertyName, textureProperty.scale); + } + + static void RemapPropertyFloat(MaterialDescription description, Material material, string inPropName, + string outPropName) + { + if (description.TryGetProperty(inPropName, out float floatProperty)) + { + material.SetFloat(outPropName, floatProperty); + } + } + + static void RemapPropertyTexture(MaterialDescription description, Material material, string inPropName, + string outPropName) + { + if (description.TryGetProperty(inPropName, out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName, textureProperty.texture); + } + } + + static void RemapPropertyTextureOrColor(MaterialDescription description, Material material, + string inPropName, string outPropName) + { + if (description.TryGetProperty(inPropName + "_map", out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName + "_MAP", textureProperty.texture); + material.SetColor(outPropName, Color.white); + } + else if (description.TryGetProperty(inPropName, out Vector4 color)) + { + material.SetColor(outPropName, color); + } + } + + static void RemapPropertyTextureOrFloat(MaterialDescription description, Material material, + string inPropName, string outPropName) + { + if (description.TryGetProperty(inPropName + "_map", out TexturePropertyDescription textureProperty)) + { + material.SetTexture(outPropName + "_MAP", textureProperty.texture); + material.SetFloat(outPropName, 1.0f); + } + else if (description.TryGetProperty(inPropName, out float floatProperty)) + { + material.SetFloat(outPropName, floatProperty); + } + } + } +} diff --git a/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs.meta b/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs.meta index 5526de3..75a5ce6 100644 --- a/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs.meta +++ b/Editor/AssetPostProcessors/PhysicalMaterial3DsMaxPreprocessor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 394142e3bac6ced4e9a0455ad99650fc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 394142e3bac6ced4e9a0455ad99650fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/ShaderGraphMaterialsUpdater.cs b/Editor/AssetPostProcessors/ShaderGraphMaterialsUpdater.cs new file mode 100644 index 0000000..dbe17f5 --- /dev/null +++ b/Editor/AssetPostProcessors/ShaderGraphMaterialsUpdater.cs @@ -0,0 +1,55 @@ +using Unity.Rendering.Universal; +using UnityEditor.ShaderGraph; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal +{ + class UniversalShaderGraphSaveContext + { + public bool updateMaterials; + } + + [InitializeOnLoad] + class ShaderGraphMaterialsUpdater + { + static ShaderGraphMaterialsUpdater() + { + GraphData.onSaveGraph += OnShaderGraphSaved; + } + + static void OnShaderGraphSaved(Shader shader, object saveContext) + { + // In case the shader is not Universal + if (!(saveContext is UniversalShaderGraphSaveContext universalSaveContext)) + return; + + if (!universalSaveContext.updateMaterials) + return; + + // Iterate over all loaded Materials + Material[] materials = Resources.FindObjectsOfTypeAll(); + try + { + for (int i = 0, length = materials.Length; i < length; i++) + { + // Only update progress bar every 10 materials + if (i % 10 == 9) + { + EditorUtility.DisplayProgressBar( + "Checking material dependencies...", + $"{i} / {length} materials.", + i / (float)(length - 1)); + } + + // Reset keywords + if (materials[i].shader.name == shader.name) + ShaderUtils.UpdateMaterial(materials[i], ShaderUtils.MaterialUpdateType.ModifiedShader); + } + } + finally + { + EditorUtility.ClearProgressBar(); + } + } + } +} diff --git a/Editor/AssetPostProcessors/ShaderGraphMaterialsUpdater.cs.meta b/Editor/AssetPostProcessors/ShaderGraphMaterialsUpdater.cs.meta new file mode 100644 index 0000000..3bf3fa9 --- /dev/null +++ b/Editor/AssetPostProcessors/ShaderGraphMaterialsUpdater.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8fa338645a1097d4a8fbcbb438c289ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs b/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs index c8f764a..7c8e312 100644 --- a/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs +++ b/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs @@ -1,94 +1,95 @@ -using System.IO; -using UnityEngine; -using UnityEditor.AssetImporters; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Rendering.Universal -{ - class SketchupMaterialDescriptionPreprocessor : AssetPostprocessor - { - static readonly uint k_Version = 1; - static readonly int k_Order = 2; - - public override uint GetVersion() - { - return k_Version; - } - - public override int GetPostprocessOrder() - { - return k_Order; - } - - public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) - { - var pipelineAsset = GraphicsSettings.currentRenderPipeline; - if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) - return; - - var lowerCasePath = Path.GetExtension(assetPath).ToLower(); - if (lowerCasePath != ".skp") - return; - - string path = AssetDatabase.GUIDToAssetPath(ShaderUtils.GetShaderGUID(ShaderPathID.Lit)); - var shader = AssetDatabase.LoadAssetAtPath(path); - if (shader == null) - return; - material.shader = shader; - - float floatProperty; - Vector4 vectorProperty; - TexturePropertyDescription textureProperty; - - if (description.TryGetProperty("DiffuseMap", out textureProperty) && textureProperty.texture!=null) - { - SetMaterialTextureProperty("_BaseMap", material, textureProperty); - SetMaterialTextureProperty("_MainTex", material, textureProperty); - var color = new Color(1.0f, 1.0f, 1.0f, 1.0f); - material.SetColor("_BaseColor", color); - material.SetColor("_Color", color); - } - else if (description.TryGetProperty("DiffuseColor", out vectorProperty)) - { - Color diffuseColor = vectorProperty; - diffuseColor = PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor; - material.SetColor("_BaseColor", diffuseColor); - material.SetColor("_Color", diffuseColor); - } - - if (description.TryGetProperty("IsTransparent", out floatProperty) && floatProperty == 1.0f) - { - material.SetFloat("_Mode", (float)3.0); // From C# enum BlendMode - material.SetOverrideTag("RenderType", "Transparent"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetInt("_ZWrite", 0); - material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; - material.SetInt("_Surface", 1); - } - else - { - material.SetFloat("_Mode", (float)0.0); // From C# enum BlendMode - material.SetOverrideTag("RenderType", ""); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.DisableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = -1; - material.SetInt("_Surface", 0); - } - } - - static void SetMaterialTextureProperty(string propertyName, Material material, TexturePropertyDescription textureProperty) - { - material.SetTexture(propertyName, textureProperty.texture); - material.SetTextureOffset(propertyName, textureProperty.offset); - material.SetTextureScale(propertyName, textureProperty.scale); - } - } -} - +using System.IO; +using UnityEngine; +using UnityEditor.AssetImporters; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class SketchupMaterialDescriptionPreprocessor : AssetPostprocessor + { + static readonly uint k_Version = 1; + static readonly int k_Order = 2; + + public override uint GetVersion() + { + return k_Version; + } + + public override int GetPostprocessOrder() + { + return k_Order; + } + + public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) + { + var pipelineAsset = GraphicsSettings.currentRenderPipeline; + if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) + return; + + var lowerCasePath = Path.GetExtension(assetPath).ToLower(); + if (lowerCasePath != ".skp") + return; + + string path = AssetDatabase.GUIDToAssetPath(ShaderUtils.GetShaderGUID(ShaderPathID.Lit)); + var shader = AssetDatabase.LoadAssetAtPath(path); + if (shader == null) + return; + material.shader = shader; + + float floatProperty; + Vector4 vectorProperty; + TexturePropertyDescription textureProperty; + + if (description.TryGetProperty("DiffuseMap", out textureProperty) && textureProperty.texture != null) + { + SetMaterialTextureProperty("_BaseMap", material, textureProperty); + SetMaterialTextureProperty("_MainTex", material, textureProperty); + var color = new Color(1.0f, 1.0f, 1.0f, 1.0f); + material.SetColor("_BaseColor", color); + material.SetColor("_Color", color); + } + else if (description.TryGetProperty("DiffuseColor", out vectorProperty)) + { + Color diffuseColor = vectorProperty; + diffuseColor = PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor; + material.SetColor("_BaseColor", diffuseColor); + material.SetColor("_Color", diffuseColor); + } + + if (description.TryGetProperty("IsTransparent", out floatProperty) && floatProperty == 1.0f) + { + material.SetFloat("_Mode", 3.0f); // From C# enum BlendMode + material.SetOverrideTag("RenderType", "Transparent"); + material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One); + material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetFloat("_ZWrite", 0.0f); + material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; + material.SetFloat("_Surface", 1.0f); + material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + else + { + material.SetFloat("_Mode", 0.0f); // From C# enum BlendMode + material.SetOverrideTag("RenderType", ""); + material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One); + material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.Zero); + material.SetFloat("_ZWrite", 1.0f); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + material.SetFloat("_Surface", 0.0f); + material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + } + + static void SetMaterialTextureProperty(string propertyName, Material material, TexturePropertyDescription textureProperty) + { + material.SetTexture(propertyName, textureProperty.texture); + material.SetTextureOffset(propertyName, textureProperty.offset); + material.SetTextureScale(propertyName, textureProperty.scale); + } + } +} diff --git a/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs.meta b/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs.meta index aeef0c7..235e98c 100644 --- a/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs.meta +++ b/Editor/AssetPostProcessors/SketchupMaterialDescriptionPostprocessor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 42eb65042d6a95942a0e667ce8fcd209 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 42eb65042d6a95942a0e667ce8fcd209 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs b/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs index 62bb5ec..70f8461 100644 --- a/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs +++ b/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs @@ -1,116 +1,117 @@ -using System; -using System.IO; -using UnityEngine; -using UnityEditor.AssetImporters; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; - -namespace UnityEditor.Rendering.Universal -{ - class ThreeDSMaterialDescriptionPreprocessor : AssetPostprocessor - { - static readonly uint k_Version = 1; - static readonly int k_Order = 2; - - public override uint GetVersion() - { - return k_Version; - } - - public override int GetPostprocessOrder() - { - return k_Order; - } - - public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) - { - var pipelineAsset = GraphicsSettings.currentRenderPipeline; - if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) - return; - - var lowerCasePath = Path.GetExtension(assetPath).ToLower(); - if (lowerCasePath != ".3ds") - return; - - string path = AssetDatabase.GUIDToAssetPath(ShaderUtils.GetShaderGUID(ShaderPathID.Lit)); - var shader = AssetDatabase.LoadAssetAtPath(path); - if (shader == null) - return; - material.shader = shader; - - TexturePropertyDescription textureProperty; - float floatProperty; - Vector4 vectorProperty; - - description.TryGetProperty("diffuse", out vectorProperty); - vectorProperty.x /= 255.0f; - vectorProperty.y /= 255.0f; - vectorProperty.z /= 255.0f; - vectorProperty.w /= 255.0f; - description.TryGetProperty("transparency", out floatProperty); - - bool isTransparent = vectorProperty.w <= 0.99f || floatProperty > .0f; - if (isTransparent) - { - material.SetFloat("_Mode", (float)3.0); // From C# enum BlendMode - material.SetOverrideTag("RenderType", "Transparent"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetInt("_ZWrite", 0); - material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; - material.SetInt("_Surface", 1); - } - else - { - material.SetFloat("_Mode", (float)0.0); // From C# enum BlendMode - material.SetOverrideTag("RenderType", ""); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.DisableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = -1; - material.SetInt("_Surface", 0); - } - - if (floatProperty > .0f) - vectorProperty.w = 1.0f - floatProperty; - - Color diffuseColor = vectorProperty; - - material.SetColor("_Color", PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor); - material.SetColor("_BaseColor", PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor); - - if (description.TryGetProperty("EmissiveColor", out vectorProperty)) - { - material.SetColor("_EmissionColor", vectorProperty); - material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; - material.EnableKeyword("_EMISSION"); - } - - if (description.TryGetProperty("texturemap1", out textureProperty)) - { - SetMaterialTextureProperty("_BaseMap", material, textureProperty); - } - - if (description.TryGetProperty("bumpmap", out textureProperty)) - { - if (material.HasProperty("_BumpMap")) - { - SetMaterialTextureProperty("_BumpMap", material, textureProperty); - material.EnableKeyword("_NORMALMAP"); - } - } - } - - static void SetMaterialTextureProperty(string propertyName, Material material, TexturePropertyDescription textureProperty) - { - material.SetTexture(propertyName, textureProperty.texture); - material.SetTextureOffset(propertyName, textureProperty.offset); - material.SetTextureScale(propertyName, textureProperty.scale); - } - } -} - +using System; +using System.IO; +using UnityEngine; +using UnityEditor.AssetImporters; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class ThreeDSMaterialDescriptionPreprocessor : AssetPostprocessor + { + static readonly uint k_Version = 1; + static readonly int k_Order = 2; + + public override uint GetVersion() + { + return k_Version; + } + + public override int GetPostprocessOrder() + { + return k_Order; + } + + public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips) + { + var pipelineAsset = GraphicsSettings.currentRenderPipeline; + if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset)) + return; + + var lowerCasePath = Path.GetExtension(assetPath).ToLower(); + if (lowerCasePath != ".3ds") + return; + + string path = AssetDatabase.GUIDToAssetPath(ShaderUtils.GetShaderGUID(ShaderPathID.Lit)); + var shader = AssetDatabase.LoadAssetAtPath(path); + if (shader == null) + return; + material.shader = shader; + + TexturePropertyDescription textureProperty; + float floatProperty; + Vector4 vectorProperty; + + description.TryGetProperty("diffuse", out vectorProperty); + vectorProperty.x /= 255.0f; + vectorProperty.y /= 255.0f; + vectorProperty.z /= 255.0f; + vectorProperty.w /= 255.0f; + description.TryGetProperty("transparency", out floatProperty); + + bool isTransparent = vectorProperty.w <= 0.99f || floatProperty > .0f; + if (isTransparent) + { + material.SetFloat("_Mode", 3.0f); // From C# enum BlendMode + material.SetOverrideTag("RenderType", "Transparent"); + material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One); + material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetFloat("_ZWrite", 0.0f); + material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; + material.SetFloat("_Surface", 1.0f); + material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + else + { + material.SetFloat("_Mode", 0.0f); // From C# enum BlendMode + material.SetOverrideTag("RenderType", ""); + material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One); + material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.Zero); + material.SetFloat("_ZWrite", 1.0f); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + material.SetFloat("_Surface", 0.0f); + material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); + } + + if (floatProperty > .0f) + vectorProperty.w = 1.0f - floatProperty; + + Color diffuseColor = vectorProperty; + + material.SetColor("_Color", PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor); + material.SetColor("_BaseColor", PlayerSettings.colorSpace == ColorSpace.Linear ? diffuseColor.gamma : diffuseColor); + + if (description.TryGetProperty("EmissiveColor", out vectorProperty)) + { + material.SetColor("_EmissionColor", vectorProperty); + material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive; + material.EnableKeyword("_EMISSION"); + } + + if (description.TryGetProperty("texturemap1", out textureProperty)) + { + SetMaterialTextureProperty("_BaseMap", material, textureProperty); + } + + if (description.TryGetProperty("bumpmap", out textureProperty)) + { + if (material.HasProperty("_BumpMap")) + { + SetMaterialTextureProperty("_BumpMap", material, textureProperty); + material.EnableKeyword("_NORMALMAP"); + } + } + } + + static void SetMaterialTextureProperty(string propertyName, Material material, TexturePropertyDescription textureProperty) + { + material.SetTexture(propertyName, textureProperty.texture); + material.SetTextureOffset(propertyName, textureProperty.offset); + material.SetTextureScale(propertyName, textureProperty.scale); + } + } +} diff --git a/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs.meta b/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs.meta index df605a4..0b7960e 100644 --- a/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs.meta +++ b/Editor/AssetPostProcessors/ThreeDSMaterialDescriptionPostprocessor.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: f0d43cb9fde29bd4cb1e030ee98868ff -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f0d43cb9fde29bd4cb1e030ee98868ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AssetVersion.cs b/Editor/AssetVersion.cs index cad0a0e..60ac5a7 100644 --- a/Editor/AssetVersion.cs +++ b/Editor/AssetVersion.cs @@ -1,9 +1,9 @@ -using UnityEngine; - -namespace UnityEditor.Rendering.Universal -{ - class AssetVersion : ScriptableObject - { - public int version; - } -} +using UnityEngine; + +namespace UnityEditor.Rendering.Universal +{ + class AssetVersion : ScriptableObject + { + public int version; + } +} diff --git a/Editor/AssetVersion.cs.meta b/Editor/AssetVersion.cs.meta index 57d3c53..3a871ff 100644 --- a/Editor/AssetVersion.cs.meta +++ b/Editor/AssetVersion.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: d0353a89b1f911e48b9e16bdc9f2e058 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: d0353a89b1f911e48b9e16bdc9f2e058 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera.meta b/Editor/Camera.meta new file mode 100644 index 0000000..d5da5db --- /dev/null +++ b/Editor/Camera.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6f5387037edf18a478a9701e9ddf3fcc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraEditor.cs b/Editor/Camera/UniversalRenderPipelineCameraEditor.cs new file mode 100644 index 0000000..a88233a --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraEditor.cs @@ -0,0 +1,505 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor.SceneManagement; +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + using Styles = UniversalRenderPipelineCameraUI.Styles; + + [CustomEditorForRenderPipeline(typeof(Camera), typeof(UniversalRenderPipelineAsset))] + [CanEditMultipleObjects] + class UniversalRenderPipelineCameraEditor : CameraEditor + { + ReorderableList m_LayerList; + + public Camera camera => target as Camera; + + List validCameras = new List(); + List m_TypeErrorCameras = new List(); + List m_OutputWarningCameras = new List(); + + UniversalRenderPipelineSerializedCamera m_SerializedCamera; + + public new void OnEnable() + { + base.OnEnable(); + settings.OnEnable(); + + m_SerializedCamera = new UniversalRenderPipelineSerializedCamera(serializedObject, settings); + + validCameras.Clear(); + m_TypeErrorCameras.Clear(); + m_OutputWarningCameras.Clear(); + + UpdateCameras(); + } + + void UpdateCameras() + { + m_SerializedCamera.Refresh(); + + m_LayerList = new ReorderableList(m_SerializedCamera.serializedObject, m_SerializedCamera.cameras, true, true, true, true) + { + drawHeaderCallback = rect => EditorGUI.LabelField(rect, Styles.cameras), + drawElementCallback = DrawElementCallback, + onSelectCallback = SelectElement, + onRemoveCallback = RemoveCamera, + onCanRemoveCallback = CanRemoveCamera, + onAddDropdownCallback = AddCameraToCameraList + }; + } + + bool CanRemoveCamera(ReorderableList list) => m_SerializedCamera.numCameras > 0; + + void RemoveCamera(ReorderableList list) + { + // As multi selection is disabled, selectedIndices will only return 1 element, remove that element from the list + if (list.selectedIndices.Any()) + { + m_SerializedCamera.cameras.DeleteArrayElementAtIndex(list.selectedIndices.First()); + } + else + { + // Nothing selected, remove the last item on the list + ReorderableList.defaultBehaviours.DoRemoveButton(list); + } + + // Force update the list as removed camera could been there + m_TypeErrorCameras.Clear(); + m_OutputWarningCameras.Clear(); + } + + void SelectElement(ReorderableList list) + { + var element = m_SerializedCamera.cameras.GetArrayElementAtIndex(list.index); + var cam = element.objectReferenceValue as Camera; + if (Event.current.clickCount == 2) + { + Selection.activeObject = cam; + } + + EditorGUIUtility.PingObject(cam); + } + + void DrawElementCallback(Rect rect, int index, bool isActive, bool isFocused) + { + rect.height = EditorGUIUtility.singleLineHeight; + rect.y += 1; + + (Camera camera, UniversalRenderPipelineSerializedCamera serializedCamera) overlayCamera = m_SerializedCamera[index]; + Camera cam = overlayCamera.camera; + if (cam != null) + { + bool typeError = false; + var type = cam.gameObject.GetComponent().renderType; + if (type != CameraRenderType.Overlay) + { + typeError = true; + if (!m_TypeErrorCameras.Contains(cam)) + { + m_TypeErrorCameras.Add(cam); + } + } + else if (m_TypeErrorCameras.Contains(cam)) + { + m_TypeErrorCameras.Remove(cam); + } + + bool outputWarning = false; + if (IsStackCameraOutputDirty(cam, overlayCamera.serializedCamera)) + { + outputWarning = true; + if (!m_OutputWarningCameras.Contains(cam)) + { + m_OutputWarningCameras.Add(cam); + } + } + else if (m_OutputWarningCameras.Contains(cam)) + { + m_OutputWarningCameras.Remove(cam); + } + + GUIContent nameContent = + outputWarning ? + EditorGUIUtility.TrTextContent(cam.name, "Output properties do not match base camera", CoreEditorStyles.iconWarn) : + EditorGUIUtility.TrTextContent(cam.name); + + GUIContent typeContent = + typeError ? + EditorGUIUtility.TrTextContent(type.GetName(), "Not a supported type", CoreEditorStyles.iconFail) : + EditorGUIUtility.TrTextContent(type.GetName()); + + EditorGUI.BeginProperty(rect, GUIContent.none, m_SerializedCamera.cameras.GetArrayElementAtIndex(index)); + var labelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth -= 20f; + + using (var iconSizeScope = new EditorGUIUtility.IconSizeScope(new Vector2(rect.height, rect.height))) + { + EditorGUI.LabelField(rect, nameContent, typeContent); + } + + // Printing if Post Processing is on or not. + var isPostActive = cam.gameObject.GetComponent().renderPostProcessing; + if (isPostActive) + { + Rect selectRect = new Rect(rect.width - 20, rect.y, 50, EditorGUIUtility.singleLineHeight); + + EditorGUI.LabelField(selectRect, "PP"); + } + EditorGUI.EndProperty(); + + EditorGUIUtility.labelWidth = labelWidth; + } + else + { + camera.GetComponent().UpdateCameraStack(); + + // Need to clean out the errorCamera list here. + m_TypeErrorCameras.Clear(); + m_OutputWarningCameras.Clear(); + } + } + + // Modified version of StageHandle.FindComponentsOfType() + // This version more closely represents unity object referencing restrictions. + // I added these restrictions: + // - Can not reference scene object outside scene + // - Can not reference cross scenes + // - Can reference child objects if it is prefab + Camera[] FindCamerasToReference(GameObject gameObject) + { + var scene = gameObject.scene; + + var inScene = !EditorUtility.IsPersistent(camera) || scene.IsValid(); + var inPreviewScene = EditorSceneManager.IsPreviewScene(scene) && scene.IsValid(); + var inCurrentScene = !EditorUtility.IsPersistent(camera) && scene.IsValid(); + + Camera[] cameras = Resources.FindObjectsOfTypeAll(); + List result = new List(); + if (!inScene) + { + foreach (var camera in cameras) + { + if (camera.transform.IsChildOf(gameObject.transform)) + result.Add(camera); + } + } + else if (inPreviewScene) + { + foreach (var camera in cameras) + { + if (camera.gameObject.scene == scene) + result.Add(camera); + } + } + else if (inCurrentScene) + { + foreach (var camera in cameras) + { + if (!EditorUtility.IsPersistent(camera) && !EditorSceneManager.IsPreviewScene(camera.gameObject.scene) && camera.gameObject.scene == scene) + result.Add(camera); + } + } + + return result.ToArray(); + } + + void AddCameraToCameraList(Rect rect, ReorderableList list) + { + // Need to do clear the list here otherwise the meu just fills up with more and more entries + validCameras.Clear(); + var allCameras = FindCamerasToReference(camera.gameObject); + foreach (var camera in allCameras) + { + var component = camera.gameObject.GetComponent(); + if (component != null) + { + if (component.renderType == CameraRenderType.Overlay) + { + validCameras.Add(camera); + } + } + } + + var names = new GUIContent[validCameras.Count]; + for (int i = 0; i < validCameras.Count; ++i) + { + names[i] = new GUIContent((i + 1) + " " + validCameras[i].name); + } + + if (!validCameras.Any()) + { + names = new GUIContent[1]; + names[0] = new GUIContent("No Overlay Cameras exist."); + } + EditorUtility.DisplayCustomMenu(rect, names, -1, AddCameraToCameraListMenuSelected, null); + } + + void AddCameraToCameraListMenuSelected(object userData, string[] options, int selected) + { + if (!validCameras.Any()) + return; + + m_SerializedCamera.cameras.InsertArrayElementAtIndex(m_SerializedCamera.numCameras); + m_SerializedCamera.cameras.GetArrayElementAtIndex(m_SerializedCamera.numCameras - 1).objectReferenceValue = validCameras[selected]; + m_SerializedCamera.serializedAdditionalDataObject.ApplyModifiedProperties(); + + m_SerializedCamera.Refresh(); + + (Camera camera, UniversalRenderPipelineSerializedCamera serializedCamera) overlayCamera = m_SerializedCamera[m_SerializedCamera.numCameras - 1]; + UpdateStackCameraOutput(overlayCamera.camera, overlayCamera.serializedCamera); + } + + public new void OnDisable() + { + base.OnDisable(); + } + + // IsPreset is an internal API - lets reuse the usable part of this function + // 93 is a "magic number" and does not represent a combination of other flags here + internal static bool IsPresetEditor(UnityEditor.Editor editor) + { + return (int)((editor.target as Component).gameObject.hideFlags) == 93; + } + + public override void OnInspectorGUI() + { + var rpAsset = UniversalRenderPipeline.asset; + if (rpAsset == null) + { + base.OnInspectorGUI(); + return; + } + + m_SerializedCamera.Update(); + + if (IsPresetEditor(this)) + { + UniversalRenderPipelineCameraUI.PresetInspector.Draw(m_SerializedCamera, this); + } + else + { + UniversalRenderPipelineCameraUI.Inspector.Draw(m_SerializedCamera, this); + } + + m_SerializedCamera.Apply(); + } + + private void UpdateStackCamerasToOverlay() + { + int cameraCount = m_SerializedCamera.cameras.arraySize; + for (int i = 0; i < cameraCount; ++i) + { + SerializedProperty cameraProperty = m_SerializedCamera.cameras.GetArrayElementAtIndex(i); + + var camera = cameraProperty.objectReferenceValue as Camera; + if (camera == null) + continue; + + var additionalCameraData = camera.GetComponent(); + if (additionalCameraData == null) + continue; + + Undo.RecordObject(camera, Styles.inspectorOverlayCameraText); + if (additionalCameraData.renderType == CameraRenderType.Base) + { + additionalCameraData.renderType = CameraRenderType.Overlay; + EditorUtility.SetDirty(camera); + } + } + } + + private void UpdateStackCamerasOutput() + { + int cameraCount = m_SerializedCamera.cameras.arraySize; + for (int i = 0; i < cameraCount; ++i) + { + (Camera camera, UniversalRenderPipelineSerializedCamera serializedCamera) overlayCamera = m_SerializedCamera[i]; + if (overlayCamera.camera != null) + UpdateStackCameraOutput(overlayCamera.camera, overlayCamera.serializedCamera); + } + } + + private void UpdateStackCameraOutput(Camera cam, UniversalRenderPipelineSerializedCamera serializedCamera) + { + if ((CameraRenderType)serializedCamera.cameraType.intValue == CameraRenderType.Base) + return; + + serializedCamera.Update(); + Undo.RecordObject(camera, Styles.inspectorOverlayCameraText); + + var serializedCameraSettings = serializedCamera.baseCameraSettings; + + bool isChanged = false; + + // Force same render texture + RenderTexture targetTexture = settings.targetTexture.objectReferenceValue as RenderTexture; + if (cam.targetTexture != targetTexture) + { + cam.targetTexture = targetTexture; + isChanged = true; + } + + // Force same hdr + bool allowHDR = settings.HDR.boolValue; + if (cam.allowHDR != allowHDR) + { + cam.allowHDR = allowHDR; + isChanged = true; + } + + // Force same mssa + bool allowMSSA = settings.allowMSAA.boolValue; + if (cam.allowMSAA != allowMSSA) + { + cam.allowMSAA = allowMSSA; + isChanged = true; + } + + // Force same viewport rect + Rect rect = settings.normalizedViewPortRect.rectValue; + if (cam.rect != rect) + { + cam.rect = settings.normalizedViewPortRect.rectValue; + isChanged = true; + } + + // Force same dynamic resolution + bool allowDynamicResolution = settings.allowDynamicResolution.boolValue; + if (serializedCamera.allowDynamicResolution.boolValue != allowDynamicResolution) + { + cam.allowDynamicResolution = allowDynamicResolution; + isChanged = true; + } + + // Force same target display + int targetDisplay = settings.targetDisplay.intValue; + if (cam.targetDisplay != targetDisplay) + { + cam.targetDisplay = targetDisplay; + isChanged = true; + } + +#if ENABLE_VR && ENABLE_XR_MODULE + // Force same target display + int selectedValue = !m_SerializedCamera.allowXRRendering.boolValue ? 0 : 1; + int overlayCameraSelectedValue = !serializedCamera.allowXRRendering.boolValue ? 0 : 1; + if (overlayCameraSelectedValue != selectedValue) + { + serializedCamera.allowXRRendering.boolValue = selectedValue == 1; + isChanged = true; + } +#endif + + if (isChanged) + { + EditorUtility.SetDirty(cam); + serializedCamera.Apply(); + } + } + + private bool IsStackCameraOutputDirty(Camera cam, UniversalRenderPipelineSerializedCamera serializedCamera) + { + serializedCamera.Update(); + + // Force same render texture + RenderTexture targetTexture = settings.targetTexture.objectReferenceValue as RenderTexture; + if (cam.targetTexture != targetTexture) + return true; + + // Force same hdr + bool allowHDR = settings.HDR.boolValue; + if (cam.allowHDR != allowHDR) + return true; + + // Force same mssa + bool allowMSSA = settings.allowMSAA.boolValue; + if (cam.allowMSAA != allowMSSA) + return true; + + // Force same viewport rect + Rect rect = settings.normalizedViewPortRect.rectValue; + if (cam.rect != rect) + return true; + + // Force same dynamic resolution + bool allowDynamicResolution = settings.allowDynamicResolution.boolValue; + if (serializedCamera.allowDynamicResolution.boolValue != allowDynamicResolution) + return true; + + // Force same target display + int targetDisplay = settings.targetDisplay.intValue; + if (cam.targetDisplay != targetDisplay) + return true; + +#if ENABLE_VR && ENABLE_XR_MODULE + // Force same target display + int selectedValue = !m_SerializedCamera.allowXRRendering.boolValue ? 0 : 1; + int overlayCameraSelectedValue = !serializedCamera.allowXRRendering.boolValue ? 0 : 1; + if (overlayCameraSelectedValue != selectedValue) + return true; +#endif + + return false; + } + + internal void DrawStackSettings() + { + if (m_SerializedCamera.cameras.hasMultipleDifferentValues) + { + EditorGUILayout.HelpBox("Cannot multi edit stack of multiple cameras.", MessageType.Info); + EditorGUILayout.EndFoldoutHeaderGroup(); + return; + } + + bool cameraStackingAvailable = m_SerializedCamera + .camerasAdditionalData + .All(c => c.scriptableRenderer?.supportedRenderingFeatures?.cameraStacking ?? false); + + if (!cameraStackingAvailable) + { + EditorGUILayout.HelpBox("The renderer used by this camera doesn't support camera stacking. Only Base camera will render.", MessageType.Warning); + return; + } + + EditorGUILayout.Space(); + + m_LayerList.DoLayoutList(); + m_SerializedCamera.Apply(); + + EditorGUI.indentLevel--; + if (m_TypeErrorCameras.Any()) + { + var message = new StringBuilder(); + message.Append("The type of the following Cameras must be Overlay render type: "); + foreach (var cam in m_TypeErrorCameras) + { + message.Append(cam.name); + message.Append(cam != m_TypeErrorCameras.Last() ? ", " : "."); + } + + CoreEditorUtils.DrawFixMeBox(message.ToString(), MessageType.Error, UpdateStackCamerasToOverlay); + } + + if (m_OutputWarningCameras.Any()) + { + var message = new StringBuilder(); + message.Append("The output properties of this Camera do not match the output properties of the following Cameras: "); + foreach (var cam in m_OutputWarningCameras) + { + message.Append(cam.name); + message.Append(cam != m_OutputWarningCameras.Last() ? ", " : "."); + } + + CoreEditorUtils.DrawFixMeBox(message.ToString(), MessageType.Warning, () => UpdateStackCamerasOutput()); + } + EditorGUI.indentLevel++; + + EditorGUILayout.Space(); + } + } +} diff --git a/Editor/UniversalRenderPipelineCameraEditor.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraEditor.cs.meta similarity index 95% rename from Editor/UniversalRenderPipelineCameraEditor.cs.meta rename to Editor/Camera/UniversalRenderPipelineCameraEditor.cs.meta index d6dbb74..918492a 100644 --- a/Editor/UniversalRenderPipelineCameraEditor.cs.meta +++ b/Editor/Camera/UniversalRenderPipelineCameraEditor.cs.meta @@ -1,13 +1,13 @@ -fileFormatVersion: 2 -guid: d569aa2a3d2a1a74aaf68c388f2e0798 -timeCreated: 1509983694 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: d569aa2a3d2a1a74aaf68c388f2e0798 +timeCreated: 1509983694 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs new file mode 100644 index 0000000..094e2cb --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs @@ -0,0 +1,106 @@ +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + using CED = CoreEditorDrawer; + + static partial class UniversalRenderPipelineCameraUI + { + [URPHelpURL("camera-component-reference")] + public enum Expandable + { + /// Projection + Projection = 1 << 0, + /// Physical + Physical = 1 << 1, + /// Output + Output = 1 << 2, + /// Orthographic + Orthographic = 1 << 3, + /// RenderLoop + RenderLoop = 1 << 4, + /// Rendering + Rendering = 1 << 5, + /// Environment + Environment = 1 << 6, + /// Stack + Stack = 1 << 7, + } + + static readonly ExpandedState k_ExpandedState = new(Expandable.Projection, "URP"); + + public static readonly CED.IDrawer SectionProjectionSettings = CED.FoldoutGroup( + CameraUI.Styles.projectionSettingsHeaderContent, + Expandable.Projection, + k_ExpandedState, + FoldoutOption.Indent, + CED.Group( + DrawerProjection + ), + PhysicalCamera.Drawer + ); + + public static readonly CED.IDrawer SectionStackSettings = + CED.Conditional( + (serialized, editor) => (CameraRenderType)serialized.cameraType.intValue == CameraRenderType.Base, + CED.FoldoutGroup(Styles.stackSettingsText, Expandable.Stack, k_ExpandedState, FoldoutOption.Indent, CED.Group(DrawerStackCameras))); + + public static readonly CED.IDrawer[] Inspector = + { + CED.Group( + DrawerCameraType + ), + SectionProjectionSettings, + Rendering.Drawer, + SectionStackSettings, + Environment.Drawer, + Output.Drawer + }; + + static void DrawerProjection(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + var camera = p.serializedObject.targetObject as Camera; + bool pixelPerfectEnabled = camera.TryGetComponent(out var pixelPerfectCamera) && pixelPerfectCamera.enabled; + if (pixelPerfectEnabled) + EditorGUILayout.HelpBox(Styles.pixelPerfectInfo, MessageType.Info); + + using (new EditorGUI.DisabledGroupScope(pixelPerfectEnabled)) + CameraUI.Drawer_Projection(p, owner); + } + + static void DrawerCameraType(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + int selectedRenderer = p.renderer.intValue; + ScriptableRenderer scriptableRenderer = UniversalRenderPipeline.asset.GetRenderer(selectedRenderer); + bool isDeferred = scriptableRenderer is UniversalRenderer { renderingMode: RenderingMode.Deferred }; + + EditorGUI.BeginChangeCheck(); + + CameraRenderType originalCamType = (CameraRenderType)p.cameraType.intValue; + CameraRenderType camType = (originalCamType != CameraRenderType.Base && isDeferred) ? CameraRenderType.Base : originalCamType; + + camType = (CameraRenderType)EditorGUILayout.EnumPopup( + Styles.cameraType, + camType, + e => !isDeferred || (CameraRenderType)e != CameraRenderType.Overlay, + false + ); + + if (EditorGUI.EndChangeCheck() || camType != originalCamType) + { + p.cameraType.intValue = (int)camType; + } + + EditorGUILayout.Space(); + } + + static void DrawerStackCameras(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + if (owner is UniversalRenderPipelineCameraEditor cameraEditor) + { + cameraEditor.DrawStackSettings(); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs.meta new file mode 100644 index 0000000..e17778f --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 351a090b57ba63848bc96f8dcde61a72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Drawers.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Drawers.cs new file mode 100644 index 0000000..2611a99 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Drawers.cs @@ -0,0 +1,131 @@ +namespace UnityEditor.Rendering.Universal +{ + using UnityEngine; + using UnityEngine.Rendering.Universal; + using CED = CoreEditorDrawer; + + static partial class UniversalRenderPipelineCameraUI + { + public partial class Environment + { + internal enum BackgroundType + { + Skybox = 0, + SolidColor, + [InspectorName("Uninitialized")] + DontCare, + } + + public static readonly CED.IDrawer Drawer = CED.FoldoutGroup( + CameraUI.Environment.Styles.header, + Expandable.Environment, + k_ExpandedState, + FoldoutOption.Indent, + CED.Conditional( + (serialized, owner) => (CameraRenderType)serialized.cameraType.intValue == CameraRenderType.Base, + CED.Group( + Drawer_Environment_ClearFlags + ) + ), + CED.Group( + Styles.volumesSettingsText, + CED.Group( + GroupOption.Indent, + Drawer_Environment_VolumeUpdate, + CameraUI.Environment.Drawer_Environment_VolumeLayerMask, + Drawer_Environment_VolumeTrigger + ) + ) + ); + + static BackgroundType GetBackgroundType(CameraClearFlags clearFlags) + { + switch (clearFlags) + { + case CameraClearFlags.Skybox: + return BackgroundType.Skybox; + case CameraClearFlags.Nothing: + return BackgroundType.DontCare; + + // DepthOnly is not supported by design in UniversalRP. We upgrade it to SolidColor + default: + return BackgroundType.SolidColor; + } + } + + static void Drawer_Environment_ClearFlags(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUI.showMixedValue = p.baseCameraSettings.clearFlags.hasMultipleDifferentValues; + + Rect clearFlagsRect = EditorGUILayout.GetControlRect(); + EditorGUI.BeginProperty(clearFlagsRect, Styles.backgroundType, p.baseCameraSettings.clearFlags); + { + EditorGUI.BeginChangeCheck(); + BackgroundType backgroundType = GetBackgroundType((CameraClearFlags)p.baseCameraSettings.clearFlags.intValue); + var selectedValue = (BackgroundType)EditorGUI.EnumPopup(clearFlagsRect, Styles.backgroundType, backgroundType); + if (EditorGUI.EndChangeCheck()) + { + CameraClearFlags selectedClearFlags; + switch (selectedValue) + { + case BackgroundType.Skybox: + selectedClearFlags = CameraClearFlags.Skybox; + break; + + case BackgroundType.DontCare: + selectedClearFlags = CameraClearFlags.Nothing; + break; + + default: + selectedClearFlags = CameraClearFlags.SolidColor; + break; + } + + p.baseCameraSettings.clearFlags.intValue = (int)selectedClearFlags; + } + + if (!p.baseCameraSettings.clearFlags.hasMultipleDifferentValues) + { + if (GetBackgroundType((CameraClearFlags)p.baseCameraSettings.clearFlags.intValue) == BackgroundType.SolidColor) + { + using (var group = new EditorGUI.IndentLevelScope()) + { + p.baseCameraSettings.DrawBackgroundColor(); + } + } + } + } + EditorGUI.EndProperty(); + EditorGUI.showMixedValue = false; + } + + static void Drawer_Environment_VolumeUpdate(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUI.BeginChangeCheck(); + VolumeFrameworkUpdateMode prevVolumeUpdateMode = (VolumeFrameworkUpdateMode)p.volumeFrameworkUpdateMode.intValue; + EditorGUILayout.PropertyField(p.volumeFrameworkUpdateMode, Styles.volumeUpdates); + if (EditorGUI.EndChangeCheck()) + { + if (p.serializedObject.targetObject is not Camera cam) + return; + + VolumeFrameworkUpdateMode curVolumeUpdateMode = (VolumeFrameworkUpdateMode)p.volumeFrameworkUpdateMode.intValue; + cam.SetVolumeFrameworkUpdateMode(curVolumeUpdateMode); + } + } + + static void Drawer_Environment_VolumeTrigger(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + var controlRect = EditorGUILayout.GetControlRect(true); + EditorGUI.BeginProperty(controlRect, Styles.volumeTrigger, p.volumeTrigger); + { + EditorGUI.BeginChangeCheck(); + var newValue = EditorGUI.ObjectField(controlRect, Styles.volumeTrigger, (Transform)p.volumeTrigger.objectReferenceValue, typeof(Transform), true); + if (EditorGUI.EndChangeCheck() && !Equals(p.volumeTrigger.objectReferenceValue, newValue)) + p.volumeTrigger.objectReferenceValue = newValue; + } + EditorGUI.EndProperty(); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Drawers.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Drawers.cs.meta new file mode 100644 index 0000000..f1959fa --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Drawers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b68aaae4e9af09d4d965e4cc2f6c8fcd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Skin.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Skin.cs new file mode 100644 index 0000000..670ddfb --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Skin.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace UnityEditor.Rendering.Universal +{ + static partial class UniversalRenderPipelineCameraUI + { + public partial class Environment + { + public class Styles + { + public static GUIContent backgroundType = EditorGUIUtility.TrTextContent("Background Type", "Controls how to initialize the Camera's background.\n\nSkybox initializes camera with Skybox, defaulting to a background color if no skybox is found.\n\nSolid Color initializes background with the background color.\n\nUninitialized has undefined values for the camera background. Use this only if you are rendering all pixels in the Camera's view."); + public static GUIContent volumesSettingsText = EditorGUIUtility.TrTextContent("Volumes", "These settings define how Volumes affect this Camera."); + public static GUIContent volumeTrigger = EditorGUIUtility.TrTextContent("Volume Trigger", "A transform that will act as a trigger for volume blending. If none is set, the camera itself will act as a trigger."); + public static GUIContent volumeUpdates = EditorGUIUtility.TrTextContent("Update Mode", "Select how Unity updates Volumes: every frame or when triggered via scripting. In the Editor, Unity updates Volumes every frame when not in the Play mode."); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Skin.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Skin.cs.meta new file mode 100644 index 0000000..8a13841 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Environment.Skin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a4aae3b1d854784897c1039b8168a08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Drawers.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Drawers.cs new file mode 100644 index 0000000..bb4c24f --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Drawers.cs @@ -0,0 +1,245 @@ +using System; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + using CED = CoreEditorDrawer; + + static partial class UniversalRenderPipelineCameraUI + { + public partial class Output + { + public static readonly CED.IDrawer Drawer = CED.Conditional( + (serialized, owner) => (CameraRenderType)serialized.cameraType.intValue == CameraRenderType.Base, + CED.FoldoutGroup( + CameraUI.Output.Styles.header, + Expandable.Output, + k_ExpandedState, + FoldoutOption.Indent, + CED.Group( + DrawerOutputTargetTexture + ), + CED.Conditional( + (serialized, owner) => serialized.serializedObject.targetObject is Camera camera && camera.targetTexture == null, + CED.Group( + DrawerOutputMultiDisplay + ) + ), +#if ENABLE_VR && ENABLE_XR_MODULE + CED.Group(DrawerOutputXRRendering), +#endif + CED.Group( + DrawerOutputNormalizedViewPort + ), + CED.Conditional( + (serialized, owner) => serialized.serializedObject.targetObject is Camera camera && camera.targetTexture == null, + CED.Group( + DrawerOutputHDR, + DrawerOutputMSAA, + DrawerOutputAllowDynamicResolution + ) + ) + ) + ); + + static void DrawerOutputMultiDisplay(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + p.baseCameraSettings.DrawMultiDisplay(); + if (checkScope.changed) + { + UpdateStackCamerasOutput(p, camera => + { + bool isChanged = false; + // Force same target display + int targetDisplay = p.baseCameraSettings.targetDisplay.intValue; + if (camera.targetDisplay != targetDisplay) + { + camera.targetDisplay = targetDisplay; + isChanged = true; + } + + // Force same target display + StereoTargetEyeMask stereoTargetEye = (StereoTargetEyeMask)p.baseCameraSettings.targetEye.intValue; + if (camera.stereoTargetEye != stereoTargetEye) + { + camera.stereoTargetEye = stereoTargetEye; + isChanged = true; + } + + return isChanged; + }); + } + } + } + + static void DrawerOutputAllowDynamicResolution(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + CameraUI.Output.Drawer_Output_AllowDynamicResolution(p, owner); + if (checkScope.changed) + { + UpdateStackCamerasOutput(p, camera => + { + bool allowDynamicResolution = p.allowDynamicResolution.boolValue; + + if (camera.allowDynamicResolution == p.allowDynamicResolution.boolValue) + return false; + + EditorUtility.SetDirty(camera); + + camera.allowDynamicResolution = allowDynamicResolution; + return true; + }); + } + } + } + + static void DrawerOutputNormalizedViewPort(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + CameraUI.Output.Drawer_Output_NormalizedViewPort(p, owner); + if (checkScope.changed) + { + UpdateStackCamerasOutput(p, camera => + { + Rect rect = p.baseCameraSettings.normalizedViewPortRect.rectValue; + if (camera.rect != rect) + { + camera.rect = p.baseCameraSettings.normalizedViewPortRect.rectValue; + return true; + } + + return false; + }); + } + } + } + + static void UpdateStackCamerasOutput(UniversalRenderPipelineSerializedCamera p, Func updateOutputProperty) + { + int cameraCount = p.cameras.arraySize; + for (int i = 0; i < cameraCount; ++i) + { + SerializedProperty cameraProperty = p.cameras.GetArrayElementAtIndex(i); + Camera overlayCamera = cameraProperty.objectReferenceValue as Camera; + if (overlayCamera != null) + { + Undo.RecordObject(overlayCamera, Styles.inspectorOverlayCameraText); + if (updateOutputProperty(overlayCamera)) + EditorUtility.SetDirty(overlayCamera); + } + } + } + + static void DrawerOutputTargetTexture(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + var rpAsset = UniversalRenderPipeline.asset; + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + EditorGUILayout.PropertyField(p.baseCameraSettings.targetTexture, Styles.targetTextureLabel); + + var texture = p.baseCameraSettings.targetTexture.objectReferenceValue as RenderTexture; + if (!p.baseCameraSettings.targetTexture.hasMultipleDifferentValues && rpAsset != null) + { + int pipelineSamplesCount = rpAsset.msaaSampleCount; + + if (texture && texture.antiAliasing > pipelineSamplesCount) + { + string pipelineMSAACaps = (pipelineSamplesCount > 1) ? string.Format(Styles.pipelineMSAACapsSupportSamples, pipelineSamplesCount) : Styles.pipelineMSAACapsDisabled; + EditorGUILayout.HelpBox(string.Format(Styles.cameraTargetTextureMSAA, texture.antiAliasing, pipelineMSAACaps), MessageType.Warning, true); + } + } + + if (checkScope.changed) + { + UpdateStackCamerasOutput(p, camera => + { + if (camera.targetTexture == texture) + return false; + + camera.targetTexture = texture; + return true; + }); + } + } + } + +#if ENABLE_VR && ENABLE_XR_MODULE + static void DrawerOutputXRRendering(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + Rect controlRect = EditorGUILayout.GetControlRect(true); + EditorGUI.BeginProperty(controlRect, Styles.xrTargetEye, p.allowXRRendering); + { + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + int selectedValue = !p.allowXRRendering.boolValue ? 0 : 1; + bool allowXRRendering = EditorGUI.IntPopup(controlRect, Styles.xrTargetEye, selectedValue, Styles.xrTargetEyeOptions, Styles.xrTargetEyeValues) == 1; + if (checkScope.changed) + p.allowXRRendering.boolValue = allowXRRendering; + } + } + EditorGUI.EndProperty(); + } + +#endif + + static void DrawerOutputHDR(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + Rect controlRect = EditorGUILayout.GetControlRect(true); + EditorGUI.BeginProperty(controlRect, Styles.allowHDR, p.baseCameraSettings.HDR); + { + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + int selectedValue = !p.baseCameraSettings.HDR.boolValue ? 0 : 1; + var allowHDR = EditorGUI.IntPopup(controlRect, Styles.allowHDR, selectedValue, Styles.displayedCameraOptions, Styles.cameraOptions) == 1; + if (checkScope.changed) + { + p.baseCameraSettings.HDR.boolValue = allowHDR; + UpdateStackCamerasOutput(p, camera => + { + if (camera.allowHDR == allowHDR) + return false; + + camera.allowHDR = allowHDR; + return true; + }); + } + } + } + EditorGUI.EndProperty(); + } + + static void DrawerOutputMSAA(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + Rect controlRect = EditorGUILayout.GetControlRect(true); + EditorGUI.BeginProperty(controlRect, Styles.allowMSAA, p.baseCameraSettings.allowMSAA); + { + using (var checkScope = new EditorGUI.ChangeCheckScope()) + { + int selectedValue = !p.baseCameraSettings.allowMSAA.boolValue ? 0 : 1; + var allowMSAA = EditorGUI.IntPopup(controlRect, Styles.allowMSAA, + selectedValue, Styles.displayedCameraOptions, Styles.cameraOptions) == 1; + if (checkScope.changed) + { + p.baseCameraSettings.allowMSAA.boolValue = allowMSAA; + UpdateStackCamerasOutput(p, camera => + { + if (camera.allowMSAA == allowMSAA) + return false; + + camera.allowMSAA = allowMSAA; + return true; + }); + } + } + } + EditorGUI.EndProperty(); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Drawers.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Drawers.cs.meta new file mode 100644 index 0000000..7f0b81f --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Drawers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a6bc694ac42d3343b113dd49606145c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Skin.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Skin.cs new file mode 100644 index 0000000..4db2a67 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Skin.cs @@ -0,0 +1,43 @@ +using UnityEngine; + +namespace UnityEditor.Rendering.Universal +{ + static partial class UniversalRenderPipelineCameraUI + { + public partial class Output + { + public class Styles + { +#if ENABLE_VR && ENABLE_XR_MODULE + public static GUIContent[] xrTargetEyeOptions = + { + EditorGUIUtility.TrTextContent("None"), + EditorGUIUtility.TrTextContent("Both"), + }; + + public static int[] xrTargetEyeValues = { 0, 1 }; + public static readonly GUIContent xrTargetEye = EditorGUIUtility.TrTextContent("Target Eye", + "Allows XR rendering if target eye sets to both eye. Disable XR for this camera otherwise."); +#endif + // Using the pipeline Settings + public static GUIContent[] displayedCameraOptions = + { + EditorGUIUtility.TrTextContent("Off"), + EditorGUIUtility.TrTextContent("Use settings from Render Pipeline Asset"), + }; + + public static int[] cameraOptions = { 0, 1 }; + + public static readonly GUIContent targetTextureLabel = EditorGUIUtility.TrTextContent("Output Texture", "The texture to render this camera into, if none then this camera renders to screen."); + + public static string inspectorOverlayCameraText = L10n.Tr("Inspector Overlay Camera"); + public static GUIContent allowMSAA = EditorGUIUtility.TrTextContent("MSAA", "Enables Multi-Sample Anti-Aliasing, a technique that smooths jagged edges."); + public static GUIContent allowHDR = EditorGUIUtility.TrTextContent("HDR", "High Dynamic Range gives you a wider range of light intensities, so your lighting looks more realistic. With it, you can still see details and experience less saturation even with bright light.", (Texture)null); + + public static string cameraTargetTextureMSAA = L10n.Tr("Camera target texture requires {0}x MSAA. Universal pipeline {1}."); + public static string pipelineMSAACapsSupportSamples = L10n.Tr("is set to support {0}x"); + public static string pipelineMSAACapsDisabled = L10n.Tr("has MSAA disabled"); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Skin.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Skin.cs.meta new file mode 100644 index 0000000..d09e7bf --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Output.Skin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcc213569e3849641896accd4ad61e24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.PhysicalCamera.Drawers.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.PhysicalCamera.Drawers.cs new file mode 100644 index 0000000..b79f054 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.PhysicalCamera.Drawers.cs @@ -0,0 +1,32 @@ +namespace UnityEditor.Rendering.Universal +{ + using CED = CoreEditorDrawer; + + static partial class UniversalRenderPipelineCameraUI + { + public partial class PhysicalCamera + { + public static readonly CED.IDrawer Drawer = CED.Conditional( + (serialized, owner) => serialized.projectionMatrixMode.intValue == (int)CameraUI.ProjectionMatrixMode.PhysicalPropertiesBased, + CED.Group( + CameraUI.PhysicalCamera.Styles.cameraBody, + GroupOption.Indent, + CED.Group( + GroupOption.Indent, + CameraUI.PhysicalCamera.Drawer_PhysicalCamera_CameraBody_Sensor, + CameraUI.PhysicalCamera.Drawer_PhysicalCamera_CameraBody_GateFit + ) + ), + CED.Group( + CameraUI.PhysicalCamera.Styles.lens, + GroupOption.Indent, + CED.Group( + GroupOption.Indent, + CameraUI.PhysicalCamera.Drawer_PhysicalCamera_Lens_FocalLength, + CameraUI.PhysicalCamera.Drawer_PhysicalCamera_Lens_Shift + ) + ) + ); + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.PhysicalCamera.Drawers.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.PhysicalCamera.Drawers.cs.meta new file mode 100644 index 0000000..6435fb6 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.PhysicalCamera.Drawers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14ecd35dd3ee4504c84e850f72cac9b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.PresetInspector.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.PresetInspector.cs new file mode 100644 index 0000000..0ecd9ab --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.PresetInspector.cs @@ -0,0 +1,28 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + using CED = CoreEditorDrawer; + + static partial class UniversalRenderPipelineCameraUI + { + static readonly ExpandedState k_ExpandedStatePreset = new(0, "URP-preset"); + + public static readonly CED.IDrawer PresetInspector = CED.Group( + CED.Group((serialized, owner) => + EditorGUILayout.HelpBox(CameraUI.Styles.unsupportedPresetPropertiesMessage, MessageType.Info)), + CED.Group((serialized, owner) => EditorGUILayout.Space()), + CED.FoldoutGroup( + CameraUI.Styles.projectionSettingsHeaderContent, + Expandable.Projection, + k_ExpandedStatePreset, + FoldoutOption.Indent, + CED.Group( + CameraUI.Drawer_Projection), + PhysicalCamera.Drawer), + Rendering.DrawerPreset + ); + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.PresetInspector.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.PresetInspector.cs.meta new file mode 100644 index 0000000..ba5b9bd --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.PresetInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00fb6a10a5e37ea478b701ae3a51736e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs new file mode 100644 index 0000000..e8c6ae3 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs @@ -0,0 +1,236 @@ +using System.Linq; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + using CED = CoreEditorDrawer; + + static partial class UniversalRenderPipelineCameraUI + { + public partial class Rendering + { + static bool s_PostProcessingWarningShown = false; + + static readonly CED.IDrawer PostProcessingWarningInit = CED.Group( + (serialized, owner) => s_PostProcessingWarningShown = false + ); + + private static readonly CED.IDrawer PostProcessingWarningDrawer = CED.Conditional( + (serialized, owner) => IsAnyRendererHasPostProcessingEnabled(serialized, UniversalRenderPipeline.asset) && serialized.renderPostProcessing.boolValue, + (serialized, owner) => + { + EditorGUILayout.HelpBox(Styles.disabledPostprocessing, MessageType.Warning); + s_PostProcessingWarningShown = true; + }); + + private static readonly CED.IDrawer PostProcessingAAWarningDrawer = CED.Conditional( + (serialized, owner) => !s_PostProcessingWarningShown && IsAnyRendererHasPostProcessingEnabled(serialized, UniversalRenderPipeline.asset) && (AntialiasingMode)serialized.antialiasing.intValue != AntialiasingMode.None, + (serialized, owner) => + { + EditorGUILayout.HelpBox(Styles.disabledPostprocessing, MessageType.Warning); + s_PostProcessingWarningShown = true; + }); + + private static readonly CED.IDrawer PostProcessingStopNaNsWarningDrawer = CED.Conditional( + (serialized, owner) => !s_PostProcessingWarningShown && IsAnyRendererHasPostProcessingEnabled(serialized, UniversalRenderPipeline.asset) && serialized.stopNaNs.boolValue, + (serialized, owner) => + { + EditorGUILayout.HelpBox(Styles.disabledPostprocessing, MessageType.Warning); + s_PostProcessingWarningShown = true; + }); + + private static readonly CED.IDrawer PostProcessingDitheringWarningDrawer = CED.Conditional( + (serialized, owner) => !s_PostProcessingWarningShown && IsAnyRendererHasPostProcessingEnabled(serialized, UniversalRenderPipeline.asset) && serialized.dithering.boolValue, + (serialized, owner) => + { + EditorGUILayout.HelpBox(Styles.disabledPostprocessing, MessageType.Warning); + s_PostProcessingWarningShown = true; + }); + + static readonly CED.IDrawer BaseCameraRenderTypeDrawer = CED.Conditional( + (serialized, owner) => (CameraRenderType)serialized.cameraType.intValue == CameraRenderType.Base, + CED.Group( + DrawerRenderingRenderPostProcessing + ), + PostProcessingWarningDrawer, + CED.Group( + DrawerRenderingAntialiasing + ), + PostProcessingAAWarningDrawer, + CED.Conditional( + (serialized, owner) => !serialized.antialiasing.hasMultipleDifferentValues, + CED.Group( + GroupOption.Indent, + CED.Conditional( + (serialized, owner) => (AntialiasingMode)serialized.antialiasing.intValue == + AntialiasingMode.SubpixelMorphologicalAntiAliasing, + CED.Group( + DrawerRenderingSMAAQuality + ) + ) + ) + ), + CED.Group( + CameraUI.Rendering.Drawer_Rendering_StopNaNs + ), + PostProcessingStopNaNsWarningDrawer, + CED.Conditional( + (serialized, owner) => serialized.stopNaNs.boolValue && CoreEditorUtils.buildTargets.Contains(GraphicsDeviceType.OpenGLES2), + (serialized, owner) => EditorGUILayout.HelpBox(Styles.stopNaNsMessage, MessageType.Warning) + ), + CED.Group( + CameraUI.Rendering.Drawer_Rendering_Dithering + ), + PostProcessingDitheringWarningDrawer, + CED.Group( + DrawerRenderingRenderShadows, + DrawerRenderingPriority, + DrawerRenderingOpaqueTexture, + DrawerRenderingDepthTexture + ) + ); + + static readonly CED.IDrawer OverlayCameraRenderTypeDrawer = CED.Conditional( + (serialized, owner) => (CameraRenderType)serialized.cameraType.intValue == CameraRenderType.Overlay, + CED.Group( + DrawerRenderingRenderPostProcessing + ), + PostProcessingWarningDrawer, + CED.Group( + DrawerRenderingClearDepth, + DrawerRenderingRenderShadows + ) + ); + + public static readonly CED.IDrawer Drawer = CED.FoldoutGroup( + CameraUI.Rendering.Styles.header, + Expandable.Rendering, + k_ExpandedState, + FoldoutOption.Indent, + PostProcessingWarningInit, + CED.Group( + DrawerRenderingRenderer + ), + BaseCameraRenderTypeDrawer, + OverlayCameraRenderTypeDrawer, + CED.Group( + CameraUI.Rendering.Drawer_Rendering_CullingMask, + CameraUI.Rendering.Drawer_Rendering_OcclusionCulling + ) + ); + + public static readonly CED.IDrawer DrawerPreset = CED.FoldoutGroup( + CameraUI.Rendering.Styles.header, + Expandable.Rendering, + k_ExpandedState, + FoldoutOption.Indent, + CED.Group( + CameraUI.Rendering.Drawer_Rendering_CullingMask, + CameraUI.Rendering.Drawer_Rendering_OcclusionCulling + ) + ); + + static void DrawerRenderingRenderer(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + var rpAsset = UniversalRenderPipeline.asset; + + int selectedRendererOption = p.renderer.intValue; + EditorGUI.BeginChangeCheck(); + + Rect controlRect = EditorGUILayout.GetControlRect(true); + EditorGUI.BeginProperty(controlRect, Styles.rendererType, p.renderer); + + EditorGUI.showMixedValue = p.renderer.hasMultipleDifferentValues; + int selectedRenderer = EditorGUI.IntPopup(controlRect, Styles.rendererType, selectedRendererOption, rpAsset.rendererDisplayList, rpAsset.rendererIndexList); + EditorGUI.EndProperty(); + if (!rpAsset.ValidateRendererDataList()) + { + EditorGUILayout.HelpBox(Styles.noRendererError, MessageType.Error); + } + else if (!rpAsset.ValidateRendererData(selectedRendererOption)) + { + EditorGUILayout.HelpBox(Styles.missingRendererWarning, MessageType.Warning); + var rect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()); + if (GUI.Button(rect, Styles.selectRenderPipelineAsset)) + { + Selection.activeObject = AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(UniversalRenderPipeline.asset)); + } + GUILayout.Space(5); + } + + if (EditorGUI.EndChangeCheck()) + p.renderer.intValue = selectedRenderer; + } + + static bool IsAnyRendererHasPostProcessingEnabled(UniversalRenderPipelineSerializedCamera p, UniversalRenderPipelineAsset rpAsset) + { + int selectedRendererOption = p.renderer.intValue; + + if (selectedRendererOption < -1 || selectedRendererOption > rpAsset.m_RendererDataList.Length || p.renderer.hasMultipleDifferentValues) + return false; + + var rendererData = selectedRendererOption == -1 ? rpAsset.m_RendererData : rpAsset.m_RendererDataList[selectedRendererOption]; + + var forwardRendererData = rendererData as UniversalRendererData; + if (forwardRendererData != null && forwardRendererData.postProcessData == null) + return true; + + var renderer2DData = rendererData as UnityEngine.Rendering.Universal.Renderer2DData; + return renderer2DData != null && renderer2DData.postProcessData == null; + } + + static void DrawerRenderingAntialiasing(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + Rect antiAliasingRect = EditorGUILayout.GetControlRect(); + EditorGUI.BeginProperty(antiAliasingRect, Styles.antialiasing, p.antialiasing); + { + EditorGUI.BeginChangeCheck(); + int selectedValue = (int)(AntialiasingMode)EditorGUI.EnumPopup(antiAliasingRect, Styles.antialiasing, (AntialiasingMode)p.antialiasing.intValue); + if (EditorGUI.EndChangeCheck()) + p.antialiasing.intValue = selectedValue; + } + EditorGUI.EndProperty(); + } + + static void DrawerRenderingClearDepth(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.clearDepth, Styles.clearDepth); + } + + static void DrawerRenderingRenderShadows(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.renderShadows, Styles.renderingShadows); + } + + static void DrawerRenderingSMAAQuality(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.antialiasingQuality, Styles.antialiasingQuality); + + if (CoreEditorUtils.buildTargets.Contains(GraphicsDeviceType.OpenGLES2)) + EditorGUILayout.HelpBox(Styles.SMAANotSupported, MessageType.Warning); + } + + static void DrawerRenderingRenderPostProcessing(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.renderPostProcessing, Styles.renderPostProcessing); + } + + static void DrawerRenderingPriority(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.baseCameraSettings.depth, Styles.priority); + } + + static void DrawerRenderingDepthTexture(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.renderDepth, Styles.requireDepthTexture); + } + + static void DrawerRenderingOpaqueTexture(UniversalRenderPipelineSerializedCamera p, Editor owner) + { + EditorGUILayout.PropertyField(p.renderOpaque, Styles.requireOpaqueTexture); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs.meta new file mode 100644 index 0000000..2cc5c08 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9bd9b1710724164c8a601affb56d19d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs new file mode 100644 index 0000000..ac65036 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs @@ -0,0 +1,35 @@ +using System.Linq; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal +{ + static partial class UniversalRenderPipelineCameraUI + { + public partial class Rendering + { + public class Styles + { + public static GUIContent rendererType = EditorGUIUtility.TrTextContent("Renderer", "The series of operations that translates code into visuals. These have different capabilities and performance characteristics."); + + public static GUIContent renderPostProcessing = EditorGUIUtility.TrTextContent("Post Processing", "Enable this to make this camera render post-processing effects."); + public static GUIContent antialiasing = EditorGUIUtility.TrTextContent("Anti-aliasing", "The method the camera uses to smooth jagged edges."); + public static GUIContent antialiasingQuality = EditorGUIUtility.TrTextContent("Quality", "The quality level to use for the selected anti-aliasing method."); + + public static GUIContent requireDepthTexture = EditorGUIUtility.TrTextContent("Depth Texture", "If this is enabled, the camera builds a screen-space depth texture. Note that generating the texture incurs a performance cost."); + public static GUIContent requireOpaqueTexture = EditorGUIUtility.TrTextContent("Opaque Texture", "If this is enabled, the camera copies the rendered view so it can be accessed at a later stage in the pipeline."); + + public static GUIContent clearDepth = EditorGUIUtility.TrTextContent("Clear Depth", "If enabled, depth from the previous camera will be cleared."); + public static GUIContent renderingShadows = EditorGUIUtility.TrTextContent("Render Shadows", "Makes this camera render shadows."); + + public static GUIContent priority = EditorGUIUtility.TrTextContent("Priority", "A camera with a higher priority is drawn on top of a camera with a lower priority [ -100, 100 ]."); + + public static readonly string noRendererError = L10n.Tr("There are no valid Renderers available on the Universal Render Pipeline asset."); + public static readonly string missingRendererWarning = L10n.Tr("The currently selected Renderer is missing from the Universal Render Pipeline asset."); + public static readonly string disabledPostprocessing = L10n.Tr("Post Processing is currently disabled on the current Universal Render Pipeline renderer."); + public static readonly string stopNaNsMessage = L10n.Tr("Stop NaNs has no effect on GLES2 platforms."); + public static readonly string SMAANotSupported = L10n.Tr("Sub-pixel Morphological Anti-Aliasing isn't supported on GLES2 platforms."); + public static readonly string selectRenderPipelineAsset = L10n.Tr("Select Render Pipeline Asset"); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs.meta new file mode 100644 index 0000000..8e7054d --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e89e471cecba0d41a66b54909f947cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Skin.cs b/Editor/Camera/UniversalRenderPipelineCameraUI.Skin.cs new file mode 100644 index 0000000..f5db653 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Skin.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace UnityEditor.Rendering.Universal +{ + static partial class UniversalRenderPipelineCameraUI + { + public class Styles + { + public static GUIContent cameraType = EditorGUIUtility.TrTextContent("Render Type", "Defines if a camera renders directly to a target or overlays on top of another camera’s output. Overlay option is not available when Deferred Render Data is in use."); + public static readonly string pixelPerfectInfo = L10n.Tr("Projection settings have been overriden by the Pixel Perfect Camera."); + + // Stack cameras + public static GUIContent stackSettingsText = EditorGUIUtility.TrTextContent("Stack", "The list of overlay cameras assigned to this camera."); + public static GUIContent cameras = EditorGUIUtility.TrTextContent("Cameras", "The list of overlay cameras assigned to this camera."); + public static string inspectorOverlayCameraText = L10n.Tr("Inspector Overlay Camera"); + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineCameraUI.Skin.cs.meta b/Editor/Camera/UniversalRenderPipelineCameraUI.Skin.cs.meta new file mode 100644 index 0000000..e16c780 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineCameraUI.Skin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d86ec93edbc4d5240ab4d8a8be938142 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Camera/UniversalRenderPipelineSerializedCamera.cs b/Editor/Camera/UniversalRenderPipelineSerializedCamera.cs new file mode 100644 index 0000000..fc41bce --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineSerializedCamera.cs @@ -0,0 +1,148 @@ +using System; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal +{ + class UniversalRenderPipelineSerializedCamera : ISerializedCamera + { + public SerializedObject serializedObject { get; } + public SerializedObject serializedAdditionalDataObject { get; } + public CameraEditor.Settings baseCameraSettings { get; } + + // This one is internal in UnityEditor for whatever reason... + public SerializedProperty projectionMatrixMode { get; } + + // Common properties + public SerializedProperty dithering { get; } + public SerializedProperty stopNaNs { get; } + public SerializedProperty allowDynamicResolution { get; } + public SerializedProperty volumeLayerMask { get; } + public SerializedProperty clearDepth { get; } + public SerializedProperty antialiasing { get; } + + // URP specific properties + public SerializedProperty renderShadows { get; } + public SerializedProperty renderDepth { get; } + public SerializedProperty renderOpaque { get; } + public SerializedProperty renderer { get; } + public SerializedProperty cameraType { get; } + public SerializedProperty cameras { get; set; } + public SerializedProperty volumeTrigger { get; } + public SerializedProperty volumeFrameworkUpdateMode { get; } + public SerializedProperty renderPostProcessing { get; } + public SerializedProperty antialiasingQuality { get; } +#if ENABLE_VR && ENABLE_XR_MODULE + public SerializedProperty allowXRRendering { get; } +#endif + + public (Camera camera, UniversalRenderPipelineSerializedCamera serializedCamera) this[int index] + { + get + { + if (index < 0 || index >= numCameras) + throw new ArgumentOutOfRangeException($"{index} is out of bounds [0 - {numCameras}]"); + + // Return the camera on that index + return (cameras.GetArrayElementAtIndex(index).objectReferenceValue as Camera, cameraSerializedObjects[index]); + } + } + + public int numCameras => cameras?.arraySize ?? 0; + + UniversalRenderPipelineSerializedCamera[] cameraSerializedObjects { get; set; } + + public UniversalAdditionalCameraData[] camerasAdditionalData { get; } + + public UniversalRenderPipelineSerializedCamera(SerializedObject serializedObject, CameraEditor.Settings settings = null) + { + this.serializedObject = serializedObject; + projectionMatrixMode = serializedObject.FindProperty("m_projectionMatrixMode"); + + allowDynamicResolution = serializedObject.FindProperty("m_AllowDynamicResolution"); + + if (settings == null) + { + baseCameraSettings = new CameraEditor.Settings(serializedObject); + baseCameraSettings.OnEnable(); + } + else + { + baseCameraSettings = settings; + } + + camerasAdditionalData = CoreEditorUtils + .GetAdditionalData(serializedObject.targetObjects); + serializedAdditionalDataObject = new SerializedObject(camerasAdditionalData); + + // Common properties + stopNaNs = serializedAdditionalDataObject.FindProperty("m_StopNaN"); + dithering = serializedAdditionalDataObject.FindProperty("m_Dithering"); + antialiasing = serializedAdditionalDataObject.FindProperty("m_Antialiasing"); + volumeLayerMask = serializedAdditionalDataObject.FindProperty("m_VolumeLayerMask"); + clearDepth = serializedAdditionalDataObject.FindProperty("m_ClearDepth"); + + // URP specific properties + renderShadows = serializedAdditionalDataObject.FindProperty("m_RenderShadows"); + renderDepth = serializedAdditionalDataObject.FindProperty("m_RequiresDepthTextureOption"); + renderOpaque = serializedAdditionalDataObject.FindProperty("m_RequiresOpaqueTextureOption"); + renderer = serializedAdditionalDataObject.FindProperty("m_RendererIndex"); + volumeLayerMask = serializedAdditionalDataObject.FindProperty("m_VolumeLayerMask"); + volumeTrigger = serializedAdditionalDataObject.FindProperty("m_VolumeTrigger"); + volumeFrameworkUpdateMode = serializedAdditionalDataObject.FindProperty("m_VolumeFrameworkUpdateModeOption"); + renderPostProcessing = serializedAdditionalDataObject.FindProperty("m_RenderPostProcessing"); + antialiasingQuality = serializedAdditionalDataObject.FindProperty("m_AntialiasingQuality"); + cameraType = serializedAdditionalDataObject.FindProperty("m_CameraType"); + +#if ENABLE_VR && ENABLE_XR_MODULE + allowXRRendering = serializedAdditionalDataObject.FindProperty("m_AllowXRRendering"); +#endif + } + + /// + /// Updates the internal serialized objects + /// + public void Update() + { + baseCameraSettings.Update(); + serializedObject.Update(); + serializedAdditionalDataObject.Update(); + + for (int i = 0; i < numCameras; ++i) + { + cameraSerializedObjects[i].Update(); + } + } + + /// + /// Applies the modified properties to the serialized objects + /// + public void Apply() + { + baseCameraSettings.ApplyModifiedProperties(); + serializedObject.ApplyModifiedProperties(); + serializedAdditionalDataObject.ApplyModifiedProperties(); + + for (int i = 0; i < numCameras; ++i) + { + cameraSerializedObjects[i].Apply(); + } + } + + /// + /// Refreshes the serialized properties from the serialized objects + /// + public void Refresh() + { + var o = new PropertyFetcher(serializedAdditionalDataObject); + cameras = o.Find("m_Cameras"); + + cameraSerializedObjects = new UniversalRenderPipelineSerializedCamera[numCameras]; + for (int i = 0; i < numCameras; ++i) + { + Camera cam = cameras.GetArrayElementAtIndex(i).objectReferenceValue as Camera; + cameraSerializedObjects[i] = new UniversalRenderPipelineSerializedCamera(new SerializedObject(cam)); + } + } + } +} diff --git a/Editor/Camera/UniversalRenderPipelineSerializedCamera.cs.meta b/Editor/Camera/UniversalRenderPipelineSerializedCamera.cs.meta new file mode 100644 index 0000000..49f0350 --- /dev/null +++ b/Editor/Camera/UniversalRenderPipelineSerializedCamera.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5d95b75d9613694da53d274b0ea27c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter.meta b/Editor/Converter.meta new file mode 100644 index 0000000..f6bd126 --- /dev/null +++ b/Editor/Converter.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e61c6cfe2da40854885b4e4d96829a88 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/AnimationClipConverter.cs b/Editor/Converter/AnimationClipConverter.cs new file mode 100644 index 0000000..646030f --- /dev/null +++ b/Editor/Converter/AnimationClipConverter.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor.Rendering.Universal.Converters; +using ClipPath = UnityEditor.Rendering.AnimationClipUpgrader.ClipPath; +using ClipProxy = UnityEditor.Rendering.AnimationClipUpgrader.AnimationClipProxy; +using UnityObject = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal +{ + internal sealed class AnimationClipConverter : RenderPipelineConverter + { + public override string name => "Animation Clip Converter"; + public override string info => "Need to update all Animation Clips. This will run after Materials has been converted."; + public override string category { get; } + public override Type container => typeof(BuiltInToURPConverterContainer); + + List m_AssetsToConvert = new List(64); + + IDictionary PropertyRenames)> m_ClipData = + new Dictionary PropertyRenames)>(); + + public override void OnInitialize(InitializeConverterContext ctx, Action callback) + { + // get paths to all animation clips + var clipPaths = AssetDatabase.FindAssets("t:AnimationClip") + .Select(p => (ClipPath)AssetDatabase.GUIDToAssetPath(p)) + .ToArray(); + + // retrieve clip assets with material animation + m_ClipData = AnimationClipUpgrader.GetAssetDataForClipsFiltered(clipPaths); + + // collect all clips and add them to the context + var keys = m_ClipData.Keys.ToArray(); + var clipIds = new GlobalObjectId[keys.Length]; + GlobalObjectId.GetGlobalObjectIdsSlow(keys.Select(c => c.Clip as UnityObject).ToArray(), clipIds); + for (int i = 0; i < keys.Length; ++i) + { + AnimationClipUpgrader.IAnimationClip key = keys[i]; + var cd = m_ClipData[key]; + var clip = key.Clip; + var item = new ConverterItemDescriptor() + { + name = clip.name, + info = cd.Path, + }; + // TODO: need to know how materials will be upgraded in order to generate warnings + m_AssetsToConvert.Add(clipIds[i]); + + ctx.AddAssetToConvert(item); + } + + callback.Invoke(); + } + + public override void OnPreRun() + { + // get paths to all animation clips + var clipPaths = new HashSet(m_ClipData.Values.Select(cd => cd.Path)); + + // get paths to all prefabs and scenes in order to inspect clip usage + var prefabPaths = AssetDatabase.FindAssets("t:Prefab") + .Select(p => (AnimationClipUpgrader.PrefabPath)AssetDatabase.GUIDToAssetPath(p)) + .ToArray(); + var scenePaths = AssetDatabase.FindAssets("t:Scene") + .Select(p => (AnimationClipUpgrader.ScenePath)AssetDatabase.GUIDToAssetPath(p)) + .ToArray(); + + // create table mapping all upgrade paths to new shaders + var upgraders = new UniversalRenderPipelineMaterialUpgrader().upgraders; + var allUpgradePathsToNewShaders = UpgradeUtility.GetAllUpgradePathsToShaders(upgraders); + + // TODO: could pass in upgrade paths used by materials in the future + + // retrieve interdependencies with prefabs to figure out which clips can be safely upgraded + AnimationClipUpgrader.GetClipDependencyMappings(clipPaths, prefabPaths, out var clipPrefabDependents, out var prefabDependencies); + AnimationClipUpgrader.GatherClipsUsageInDependentPrefabs( + clipPrefabDependents, prefabDependencies, m_ClipData, allUpgradePathsToNewShaders, default, default); + + // do the same for clips used by scenes + AnimationClipUpgrader.GetClipDependencyMappings(clipPaths, scenePaths, out var clipSceneDependents, out var sceneDependencies); + AnimationClipUpgrader.GatherClipsUsageInDependentScenes( + clipSceneDependents, sceneDependencies, m_ClipData, allUpgradePathsToNewShaders, default, default); + } + + HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)> m_Upgraded = + new HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)>(); + + HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)> m_NotUpgraded = + new HashSet<(AnimationClipUpgrader.IAnimationClip Clip, ClipPath Path, SerializedShaderPropertyUsage Usage)>(); + + IDictionary PropertyRenames)> m_TempClipData = + new Dictionary PropertyRenames)>(); + + public override void OnRun(ref RunItemContext ctx) + { + // filter flags are used to determine which clips to skip over during upgrade process + // we want to process all clips that are not ambiguously upgraded + const SerializedShaderPropertyUsage kFilterFlags = + ~( + SerializedShaderPropertyUsage.UsedByUpgraded + | SerializedShaderPropertyUsage.UsedByNonUpgraded + ); + + const SerializedShaderPropertyUsage kSuccessFlags = + SerializedShaderPropertyUsage.UsedByUpgraded; + + var clipKey = (ClipProxy)GlobalObjectId.GlobalObjectIdentifierToObjectSlow(m_AssetsToConvert[ctx.item.index]); + + m_TempClipData.Clear(); + m_TempClipData[clipKey] = m_ClipData[clipKey]; + + m_Upgraded.Clear(); + m_NotUpgraded.Clear(); + + AnimationClipUpgrader.UpgradeClips(m_TempClipData, kFilterFlags, m_Upgraded, m_NotUpgraded, default); + + var usage = m_TempClipData[clipKey].Usage; + + // Success + if ((usage & kSuccessFlags) != 0 && (usage & kFilterFlags) == 0) + return; + + if (usage == SerializedShaderPropertyUsage.Unknown) + { + ctx.didFail = true; + ctx.info = L10n.Tr("The animation clip is not used by any objects with renderers currently in the project, so it may not be safe to automatically upgrade."); + return; + } + + var sb = new StringBuilder(); + + sb.Append(L10n.Tr("The animation clip was not modified for one or more reasons:")); + + if ((usage & SerializedShaderPropertyUsage.UsedByAmbiguouslyUpgraded) != 0) + { + ctx.didFail = true; + sb.Append(L10n.Tr("\n - The animation clip is used by objects with materials that took different upgrade paths for the animated property.")); + } + + if ((usage & SerializedShaderPropertyUsage.UsedByNonUpgraded) != 0) + { + ctx.didFail = true; + sb.Append(L10n.Tr("\n - The animation clip is used by objects with materials that have not been upgraded.")); + } + + if (ctx.didFail) + ctx.info = sb.ToString(); + } + + public override void OnClicked(int index) + { + var id = m_AssetsToConvert[index]; + + var clip = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(id); + if (clip == null) + return; + + EditorGUIUtility.PingObject(clip); + } + } +} diff --git a/Editor/Converter/AnimationClipConverter.cs.meta b/Editor/Converter/AnimationClipConverter.cs.meta new file mode 100644 index 0000000..d488191 --- /dev/null +++ b/Editor/Converter/AnimationClipConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f1277c79080f894d826683283a48ecf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/BuiltInToURPConverterContainer.cs b/Editor/Converter/BuiltInToURPConverterContainer.cs new file mode 100644 index 0000000..2ebb8c6 --- /dev/null +++ b/Editor/Converter/BuiltInToURPConverterContainer.cs @@ -0,0 +1,8 @@ +namespace UnityEditor.Rendering.Universal.Converters +{ + internal sealed class BuiltInToURPConverterContainer : RenderPipelineConverterContainer + { + public override string name => "Built-in to URP"; + public override string info => "The Render Pipeline Converter performs the following tasks:\n* Converts project elements from the Built-in Render Pipeline to URP.\n* Upgrades assets from earlier URP versions to the current URP version."; + } +} diff --git a/Editor/Converter/BuiltInToURPConverterContainer.cs.meta b/Editor/Converter/BuiltInToURPConverterContainer.cs.meta new file mode 100644 index 0000000..1cc4fc6 --- /dev/null +++ b/Editor/Converter/BuiltInToURPConverterContainer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06bfd5fe09c365149b95fe3b7b98e37f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/ConversionIndexers.cs b/Editor/Converter/ConversionIndexers.cs new file mode 100644 index 0000000..ed71ba0 --- /dev/null +++ b/Editor/Converter/ConversionIndexers.cs @@ -0,0 +1,45 @@ +using UnityEditor.Search; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal.Converters +{ + static class ConversionIndexers + { + private const int k_Version = 8; + + [CustomObjectIndexer(typeof(Object), version = k_Version)] + internal static void ConversionIndexer(CustomObjectIndexerTarget context, ObjectIndexer indexer) + { + //Custom finding of all default Material properties on every single object type including custom types + if (MaterialReferenceBuilder.MaterialReferenceLookup.TryGetValue(context.targetType, out var methods)) + { + foreach (var method in methods) + { + if (method == null) continue; + + var result = method.GetMaterialFromMethod(context.target, (methodName, objectName) => + $"The method {methodName} was not found on {objectName}. This property will not be indexed."); + + if (result is Material materialResult) + { + if (materialResult != null && MaterialReferenceBuilder.GetIsReadonlyMaterial(materialResult)) + { + indexer.AddProperty("urp", "convert-readonly", context.documentIndex); + } + } + else if (result is Material[] materialArrayResult) + { + foreach (var material in materialArrayResult) + { + if (material != null && MaterialReferenceBuilder.GetIsReadonlyMaterial(material)) + { + indexer.AddProperty("urp", "convert-readonly", context.documentIndex); + } + } + } + } + } + } + } +} diff --git a/Editor/Converter/ConversionIndexers.cs.meta b/Editor/Converter/ConversionIndexers.cs.meta new file mode 100644 index 0000000..c1cdbb6 --- /dev/null +++ b/Editor/Converter/ConversionIndexers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 192e94d6ebdfb96438e2d027c77f9519 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/ConverterItemDescriptor.cs b/Editor/Converter/ConverterItemDescriptor.cs new file mode 100644 index 0000000..f9458a4 --- /dev/null +++ b/Editor/Converter/ConverterItemDescriptor.cs @@ -0,0 +1,25 @@ +using System; + +namespace UnityEditor.Rendering.Universal.Converters +{ + /// + /// A structure holding the information for each Item that needs to be Converted. + /// Name = The Name of the asset that is being converted. + /// Info = Information that can be used to store some data. This will also be shown in the UI. + /// WarningMessage = If there are some issues with the converter that we already know about. + /// Example: If we know it is a custom shader, we can not convert it so we add the information here. + /// HelpLink = Link to the documentation of how to convert this asset. Useful if the conversion failed or if we know we can not convert this asset automatically. + /// + [Serializable] + internal struct ConverterItemDescriptor + { + /// Name of the asset being converted. This will be shown in the UI. + public string name; + /// Information that can be used to store some data. This will also be shown in the UI. + public string info; + /// If there are some issues with the converter that we already know about during init phase. This will be added as a tooltip on the warning icon. + public string warningMessage; + /// Link to the documentation of how to convert this asset. Useful if the conversion failed or if we know we can not convert this asset automatically. + public string helpLink; + } +} diff --git a/Editor/Converter/ConverterItemDescriptor.cs.meta b/Editor/Converter/ConverterItemDescriptor.cs.meta new file mode 100644 index 0000000..4ff9898 --- /dev/null +++ b/Editor/Converter/ConverterItemDescriptor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 990f02521d924983aa0206159a9bfe29 +timeCreated: 1618229698 \ No newline at end of file diff --git a/Editor/Converter/ConverterItemInfo.cs b/Editor/Converter/ConverterItemInfo.cs new file mode 100644 index 0000000..aa55a4b --- /dev/null +++ b/Editor/Converter/ConverterItemInfo.cs @@ -0,0 +1,16 @@ +namespace UnityEditor.Rendering.Universal.Converters +{ + /// + /// A structure holding the information for each Item that needs to be Converted. + /// Descriptor = The ConverterItemDescriptor this item contain. + /// Index = The index for this item in the list of converter items. + /// + internal struct ConverterItemInfo + { + /// The ConverterItemDescriptor this item contain. + public ConverterItemDescriptor descriptor { get; internal set; } + + /// The index for this item in the list of converter items. + public int index { get; internal set; } + } +} diff --git a/Editor/Converter/ConverterItemInfo.cs.meta b/Editor/Converter/ConverterItemInfo.cs.meta new file mode 100644 index 0000000..ec8fceb --- /dev/null +++ b/Editor/Converter/ConverterItemInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 56f3da1aef274695815c39cc08a7be9b +timeCreated: 1618230361 \ No newline at end of file diff --git a/Editor/Converter/Converters.meta b/Editor/Converter/Converters.meta new file mode 100644 index 0000000..08d7a0b --- /dev/null +++ b/Editor/Converter/Converters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: de07e00acee5049188d7f5c776e98c91 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/Converters/RenderSettingsConverter.cs b/Editor/Converter/Converters/RenderSettingsConverter.cs new file mode 100644 index 0000000..538cd8e --- /dev/null +++ b/Editor/Converter/Converters/RenderSettingsConverter.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; +using ShadowQuality = UnityEngine.ShadowQuality; +using ShadowResolution = UnityEngine.ShadowResolution; + +namespace UnityEditor.Rendering.Universal.Converters +{ + internal class RenderSettingsConverter : RenderPipelineConverter + { + public override int priority => -9000; + public override string name => "Rendering Settings"; + + public override string info => + "This converter will look at creating Universal Render Pipeline assets and respective Renderer Assets and configure" + + " their settings based on equivalent settings from builtin renderer."; + + public override Type container => typeof(BuiltInToURPConverterContainer); + + // Used to store settings specific to Graphics Tiers + GraphicsTierSettings m_GraphicsTierSettings; + + // Settings items, currently tracks Quality settings only + List m_SettingsItems; + + // List of the rendering modes required + List m_RenderingModes; + + const string k_PipelineAssetPath = "Settings"; + + public override void OnInitialize(InitializeConverterContext context, Action callback) + { + m_SettingsItems = new List(); + m_RenderingModes = new List(); + + // check graphics tiers + GatherGraphicsTiers(); + + // check quality levels + GatherQualityLevels(ref context); + + callback?.Invoke(); + } + + /// + /// Grabs the 3rd tier from the Graphics Tier Settings based off the current build platform + /// + private void GatherGraphicsTiers() + { + var targetGrp = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); + var tier = EditorGraphicsSettings.GetTierSettings(targetGrp, GraphicsTier.Tier3); + + // Add the Graphic Tier Render Path settings as the first rendering mode + m_RenderingModes.Add(GetEquivalentRenderMode(tier.renderingPath)); + + m_GraphicsTierSettings.RenderingPath = tier.renderingPath; + m_GraphicsTierSettings.ReflectionProbeBlending = tier.reflectionProbeBlending; + m_GraphicsTierSettings.ReflectionProbeBoxProjection = tier.reflectionProbeBoxProjection; + m_GraphicsTierSettings.CascadeShadows = tier.cascadedShadowMaps; + m_GraphicsTierSettings.HDR = tier.hdr; + } + + /// + /// Iterates over all Quality Settings and saves relevant settings to a RenderSettingsItem. + /// This will also create the required information for the Render Pipeline Converter UI. + /// + /// Converter context to add elements to. + private void GatherQualityLevels(ref InitializeConverterContext context) + { + var currentQuality = QualitySettings.GetQualityLevel(); + var id = 0; + foreach (var levelName in QualitySettings.names) + { + QualitySettings.SetQualityLevel(id); + + var projectSettings = new RenderSettingItem + { + Index = id, + LevelName = levelName, + PixelLightCount = QualitySettings.pixelLightCount, + MSAA = QualitySettings.antiAliasing, + Shadows = QualitySettings.shadows, + ShadowResolution = QualitySettings.shadowResolution, + ShadowDistance = QualitySettings.shadowDistance, + ShadowCascadeCount = QualitySettings.shadowCascades, + CascadeSplit2 = QualitySettings.shadowCascade2Split, + CascadeSplit4 = QualitySettings.shadowCascade4Split, + SoftParticles = QualitySettings.softParticles, + }; + m_SettingsItems.Add(projectSettings); + + var setting = QualitySettings.GetRenderPipelineAssetAt(id); + var item = new ConverterItemDescriptor { name = $"Quality Level {id}: {levelName}" }; + + if (setting != null) + { + item.warningMessage = setting.GetType() == typeof(UniversalRenderPipelineAsset) + ? "Contains URP Asset, will override existing asset." + : "Contains SRP Asset, will override existing asset with URP asset."; + } + + context.AddAssetToConvert(item); + id++; + } + + QualitySettings.SetQualityLevel(currentQuality); + } + + public override void OnRun(ref RunItemContext context) + { + var item = context.item; + // is quality item + if (m_SettingsItems[item.index].GetType() == typeof(RenderSettingItem)) + { + GeneratePipelineAsset(m_SettingsItems[item.index] as RenderSettingItem); + } + } + + private void GeneratePipelineAsset(RenderSettingItem settings) + { + // store current quality level + var currentQualityLevel = QualitySettings.GetQualityLevel(); + + //creating pipeline asset + var asset = + ScriptableObject.CreateInstance(typeof(UniversalRenderPipelineAsset)) as UniversalRenderPipelineAsset; + if (!AssetDatabase.IsValidFolder($"Assets/{k_PipelineAssetPath}")) + AssetDatabase.CreateFolder("Assets", k_PipelineAssetPath); + var path = $"Assets/{k_PipelineAssetPath}/{settings.LevelName}_PipelineAsset.asset"; + + // Setting Pipeline Asset settings + SetPipelineSettings(asset, settings); + + // Create Renderers + var defaultIndex = 0; + var renderers = new List(); + if (m_RenderingModes.Contains(RenderingMode.Forward)) + { + renderers.Add(CreateRendererDataAsset(path, RenderingPath.Forward, "ForwardRenderer")); + if (GetEquivalentRenderMode(m_GraphicsTierSettings.RenderingPath) == RenderingMode.Forward) + defaultIndex = m_RenderingModes.IndexOf(RenderingMode.Forward); + } + + if (m_RenderingModes.Contains(RenderingMode.Deferred)) + { + renderers.Add(CreateRendererDataAsset(path, RenderingPath.DeferredShading, "DeferredRenderer")); + if (GetEquivalentRenderMode(m_GraphicsTierSettings.RenderingPath) == RenderingMode.Deferred) + defaultIndex = m_RenderingModes.IndexOf(RenderingMode.Deferred); + } + + asset.m_RendererDataList = renderers.ToArray(); + asset.m_DefaultRendererIndex = defaultIndex; + + // Create Pipeline asset on disk + AssetDatabase.CreateAsset(asset, path); + // Assign asset + QualitySettings.SetQualityLevel(settings.Index); + QualitySettings.renderPipeline = asset; + + // return to original quality level + QualitySettings.SetQualityLevel(currentQualityLevel); + // Set graphics settings + if (currentQualityLevel == settings.Index || GraphicsSettings.defaultRenderPipeline == null || GraphicsSettings.defaultRenderPipeline.GetType() != + typeof(UniversalRenderPipelineAsset)) + { + GraphicsSettings.defaultRenderPipeline = asset; + } + } + + private ScriptableRendererData CreateRendererDataAsset(string assetPath, RenderingPath renderingPath, + string fileName) + { + var rendererAsset = + UniversalRenderPipelineAsset.CreateRendererAsset(assetPath, RendererType.UniversalRenderer, true, fileName) + as UniversalRendererData; + //Missing API to set deferred or forward + rendererAsset.renderingMode = + renderingPath == RenderingPath.Forward ? RenderingMode.Forward : RenderingMode.Deferred; + //missing API to assign to pipeline asset + return rendererAsset; + } + + /// + /// Sets all relevant RP settings in order they appear in URP + /// + /// Pipeline asset to set + /// The ProjectSettingItem with stored settings + private void SetPipelineSettings(UniversalRenderPipelineAsset asset, RenderSettingItem settings) + { + // General + asset.supportsCameraDepthTexture = settings.SoftParticles; + + // Quality + asset.supportsHDR = m_GraphicsTierSettings.HDR; + asset.msaaSampleCount = settings.MSAA == 0 ? 1 : settings.MSAA; + + // Main Light + asset.mainLightRenderingMode = settings.PixelLightCount == 0 + ? LightRenderingMode.Disabled + : LightRenderingMode.PerPixel; + asset.supportsMainLightShadows = settings.Shadows != ShadowQuality.Disable; + asset.mainLightShadowmapResolution = + GetEquivalentMainlightShadowResolution((int)settings.ShadowResolution); + + // Additional Lights + asset.additionalLightsRenderingMode = settings.PixelLightCount == 0 + ? LightRenderingMode.PerVertex + : LightRenderingMode.PerPixel; + asset.maxAdditionalLightsCount = settings.PixelLightCount != 0 ? Mathf.Max(0, settings.PixelLightCount) : 4; + asset.supportsAdditionalLightShadows = settings.Shadows != ShadowQuality.Disable; + asset.additionalLightsShadowmapResolution = + GetEquivalentAdditionalLightAtlasShadowResolution((int)settings.ShadowResolution); + + // Reflection Probes + asset.reflectionProbeBlending = m_GraphicsTierSettings.ReflectionProbeBlending; + asset.reflectionProbeBoxProjection = m_GraphicsTierSettings.ReflectionProbeBoxProjection; + + // Shadows + asset.shadowDistance = settings.ShadowDistance; + asset.shadowCascadeCount = m_GraphicsTierSettings.CascadeShadows ? settings.ShadowCascadeCount : 1; + asset.cascade2Split = settings.CascadeSplit2; + asset.cascade4Split = settings.CascadeSplit4; + asset.supportsSoftShadows = settings.Shadows == ShadowQuality.All; + } + + #region HelperFunctions + + private static int GetEquivalentMainlightShadowResolution(int value) + { + return GetEquivalentShadowResolution(value); + } + + private static int GetEquivalentAdditionalLightAtlasShadowResolution(int value) + { + return GetEquivalentShadowResolution(value); + } + + private static int GetEquivalentShadowResolution(int value) + { + switch (value) + { + case 0: // low + return 1024; + case 1: // med + return 2048; + case 2: // high + return 4096; + case 3: // very high + return 4096; + default: // backup + return 1024; + } + } + + private RenderingMode GetEquivalentRenderMode(RenderingPath path) + { + switch (path) + { + case RenderingPath.VertexLit: + case RenderingPath.Forward: + return RenderingMode.Forward; + case RenderingPath.DeferredLighting: + case RenderingPath.DeferredShading: + return RenderingMode.Deferred; + default: + return RenderingMode.Forward; + } + } + + #endregion + + #region Data + + private struct GraphicsTierSettings + { + public bool ReflectionProbeBoxProjection; + public bool ReflectionProbeBlending; + public bool CascadeShadows; + public bool HDR; + public RenderingPath RenderingPath; + } + + private class SettingsItem { } + + private class RenderSettingItem : SettingsItem + { + // General + public int Index; + + public string LevelName; + + // Settings + public int PixelLightCount; + public int MSAA; + public ShadowQuality Shadows; + public ShadowResolution ShadowResolution; + public float ShadowDistance; + public int ShadowCascadeCount; + public float CascadeSplit2; + public Vector3 CascadeSplit4; + public bool SoftParticles; + } + + #endregion + } +} diff --git a/Editor/Converter/Converters/RenderSettingsConverter.cs.meta b/Editor/Converter/Converters/RenderSettingsConverter.cs.meta new file mode 100644 index 0000000..bfda512 --- /dev/null +++ b/Editor/Converter/Converters/RenderSettingsConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d641e17d0fb6a429eb81d011e79dc1ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/InitializeConverterContext.cs b/Editor/Converter/InitializeConverterContext.cs new file mode 100644 index 0000000..4648860 --- /dev/null +++ b/Editor/Converter/InitializeConverterContext.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + +namespace UnityEditor.Rendering.Universal.Converters +{ + /// + /// A structure needed for the initialization step of the converter. + /// Stores data to be visible in the UI. + /// + internal struct InitializeConverterContext + { + /// + /// Stores the list of ConverterItemDescriptor that will be filled in during the initialization step. + /// + internal List items; + + /// + /// Add to the list of assets to be converted. + /// This will be used to display information to the user in the UI. + /// + /// The item to add to the list items to convert + internal void AddAssetToConvert(ConverterItemDescriptor item) + { + items.Add(item); + } + } +} diff --git a/Editor/Converter/InitializeConverterContext.cs.meta b/Editor/Converter/InitializeConverterContext.cs.meta new file mode 100644 index 0000000..3e54626 --- /dev/null +++ b/Editor/Converter/InitializeConverterContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 52920728defd4efc99bfb3f61e16efa4 +timeCreated: 1618230672 \ No newline at end of file diff --git a/Editor/Converter/MaterialReferenceBuilder.cs b/Editor/Converter/MaterialReferenceBuilder.cs new file mode 100644 index 0000000..9d47226 --- /dev/null +++ b/Editor/Converter/MaterialReferenceBuilder.cs @@ -0,0 +1,180 @@ +using UnityEngine; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System; +using Object = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal.Converters +{ + internal static class MaterialReferenceBuilder + { + public static readonly Dictionary> MaterialReferenceLookup; + + static MaterialReferenceBuilder() + { + MaterialReferenceLookup = GetMaterialReferenceLookup(); + } + + private static Dictionary> GetMaterialReferenceLookup() + { + var result = new Dictionary>(); + + var allObjectsWithMaterialProperties = TypeCache.GetTypesDerivedFrom() + .Where(type => type.GetProperties().Any(HasMaterialProperty)); + + foreach (var property in allObjectsWithMaterialProperties) + { + if (!result.ContainsKey(property)) + { + result.Add(property, new List()); + } + + var materialProps = GetMaterialPropertiesWithoutLeaking(property); + foreach (var prop in materialProps) + { + result[property].Add(prop.GetGetMethod()); + } + } + + return result; + } + + private static bool HasMaterialProperty(PropertyInfo prop) + { + return prop.PropertyType == typeof(Material) || prop.PropertyType == typeof(Material[]); + } + + private static List GetMaterials(Object obj) + { + var result = new List(); + + var allMaterialProperties = obj.GetType().GetMaterialPropertiesWithoutLeaking(); + foreach (var property in allMaterialProperties) + { + var value = property.GetGetMethod().GetMaterialFromMethod(obj, (methodName, objectName) => + $"The method {methodName} was not found on {objectName}. This property will not be indexed."); + + if (value is Material materialResult) + { + result.Add(materialResult); + } + else if (value is Material[] materialList) + { + result.AddRange(materialList); + } + } + + return result; + } + + /// + /// Gets all of the types in the Material Reference lookup that are components. Used to determine whether to run the + /// method directly or on the component + /// + /// List of types that are components + public static List GetComponentTypes() + { + return MaterialReferenceLookup.Keys.Where(key => typeof(Component).IsAssignableFrom(key)).ToList(); + } + + /// + /// Gets all material properties from an object or a component of an object + /// + /// The GameObject or Scriptable Object + /// List of Materials + public static List GetMaterialsFromObject(Object obj) + { + var result = new List(); + + if (obj is GameObject go) + { + foreach (var key in GetComponentTypes()) + { + var components = go.GetComponentsInChildren(key); + foreach (var component in components) + { + result.AddRange(GetMaterials(component)); + } + } + } + else + { + result.AddRange(GetMaterials(obj)); + } + + return result.Distinct().ToList(); + } + + /// + /// Text Mesh pro will sometimes be missing the GetFontSharedMaterials method, even though the property is supposed + /// to have that method. This gracefully handles that case. + /// + /// The Method being invoked + /// The Unity Object the method is invoked upon + /// The function that takes the method name and object name and produces an error string + /// The resulting object from invoking the method on the Object + /// Any exception that is not the missing method exception + public static object GetMaterialFromMethod(this MethodInfo method, + Object obj, + Func generateErrorString) + { + object result = null; + try + { + result = method.Invoke(obj, null); + } + catch (Exception e) + { + // swallow the missing method exception, there's nothing we can do about it at this point + // and we've already checked for other possible null exceptions here + if ((e.InnerException is NullReferenceException)) + { + Debug.LogWarning(generateErrorString(method.Name, obj.name)); + } + else + { + throw e; + } + } + + return result; + } + + /// + /// Gets the SharedMaterial(s) properties when there are shared materials so that we don't leak material instances into the scene + /// + /// The property Type that we are getting the SharedMaterial(s) properties from + /// List of shared material properties and other material properties that won't leak material instances + public static IEnumerable GetMaterialPropertiesWithoutLeaking(this Type property) + { + var materialProps = property.GetProperties().Where(HasMaterialProperty).ToList(); + + // if there is a sharedMaterial property or sharedMaterials property, remove the property that will leak materials + var sharedMaterialProps = + materialProps.Where(prop => prop.Name.ToLowerInvariant().Contains("shared")).ToList(); + + var propsToRemove = sharedMaterialProps + .Select(prop => prop.Name.ToLowerInvariant().Replace("shared", string.Empty)) + .ToList(); + materialProps.RemoveAll(prop => propsToRemove.Contains(prop.Name.ToLowerInvariant())); + + // also remove any property which has no setter + materialProps.RemoveAll(prop => prop.SetMethod == null); + + return materialProps; + } + + /// + /// Get whether or not a Material is considered readonly (Built In Resource) + /// + /// The Material to test + /// Boolean of whether or not that Material is considered readonly + public static bool GetIsReadonlyMaterial(Material material) + { + var assetPath = AssetDatabase.GetAssetPath(material); + + return string.IsNullOrEmpty(assetPath) || assetPath.Equals(@"Resources/unity_builtin_extra", StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/Editor/Converter/MaterialReferenceBuilder.cs.meta b/Editor/Converter/MaterialReferenceBuilder.cs.meta new file mode 100644 index 0000000..6b6d4ef --- /dev/null +++ b/Editor/Converter/MaterialReferenceBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 630a22f725821a446b26d9393ed2a8c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2.meta b/Editor/Converter/PPv2.meta new file mode 100644 index 0000000..d8da90e --- /dev/null +++ b/Editor/Converter/PPv2.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: aaea8397f87188a4fb3a7451bf0ea320 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters.meta b/Editor/Converter/PPv2/EffectConverters.meta new file mode 100644 index 0000000..694b79f --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 036db18d0922d53419a5d769fe345bec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/BloomConverter.cs b/Editor/Converter/PPv2/EffectConverters/BloomConverter.cs new file mode 100644 index 0000000..f220892 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/BloomConverter.cs @@ -0,0 +1,42 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEditor; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class BloomConverter : PostProcessEffectSettingsConverter + { +#if PPV2_EXISTS + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.Bloom); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, VolumeProfile targetProfile) + { + var oldBloom = oldSettings as BIRPRendering.Bloom; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldBloom.active; + + oldBloom.clamp.Convert(newVolumeComponent.clamp); + oldBloom.diffusion.Convert(newVolumeComponent.scatter, scale: 0.05f); + oldBloom.intensity.Convert(newVolumeComponent.intensity, enabledState: oldBloom.enabled); + oldBloom.threshold.Convert(newVolumeComponent.threshold); + oldBloom.color.Convert(newVolumeComponent.tint); + oldBloom.dirtIntensity.Convert(newVolumeComponent.dirtIntensity); + oldBloom.dirtTexture.Convert(newVolumeComponent.dirtTexture); + oldBloom.fastMode.Convert(newVolumeComponent.highQualityFiltering, invertValue: true); + + // TODO: No clear conversions for these? + // newVolumeComponent.skipIterations = oldBloom.???; + // newVolumeComponent.??? = oldBloom.anamorphicRatio; + // newVolumeComponent.??? = oldBloom.softKnee; + } + +#endif + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/BloomConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/BloomConverter.cs.meta new file mode 100644 index 0000000..c5c842c --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/BloomConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65de241854404d343a0937eb1adbb6f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/ChromaticAberrationConverter.cs b/Editor/Converter/PPv2/EffectConverters/ChromaticAberrationConverter.cs new file mode 100644 index 0000000..c2e61e2 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/ChromaticAberrationConverter.cs @@ -0,0 +1,34 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEditor; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class ChromaticAberrationConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.ChromaticAberration); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + var oldChromaticAberration = oldSettings as BIRPRendering.ChromaticAberration; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldChromaticAberration.active; + + // TODO: Verify that these are 1:1 conversions for visual parity + oldChromaticAberration.intensity.Convert(newVolumeComponent.intensity, + enabledState: oldChromaticAberration.enabled); + + // TODO: No clear conversions for these? + // oldChromaticAberration.spectralLut + // oldChromaticAberration.fastMode + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/ChromaticAberrationConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/ChromaticAberrationConverter.cs.meta new file mode 100644 index 0000000..f25021f --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/ChromaticAberrationConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef31d99f657209a468edc1f49b350cb5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/ColorGradingConverter.cs b/Editor/Converter/PPv2/EffectConverters/ColorGradingConverter.cs new file mode 100644 index 0000000..55b54ae --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/ColorGradingConverter.cs @@ -0,0 +1,130 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEngine; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class ColorGradingConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.ColorGrading); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + var oldColorGrading = oldSettings as BIRPRendering.ColorGrading; + + var newTonemapping = AddVolumeComponentToAsset(targetProfile); // was: Tonemapping + var newWhiteBalance = + AddVolumeComponentToAsset(targetProfile); // was: White Balance + var newColorAdjustments = + AddVolumeComponentToAsset(targetProfile); // was: Tone + var newTargetProfile = + AddVolumeComponentToAsset(targetProfile); // was: Channel Mixer + var newLiftGammaGain = + AddVolumeComponentToAsset(targetProfile); // was: Trackballs + var newColorCurves = + AddVolumeComponentToAsset(targetProfile); // was: Grading Curves + + // Tonemapping + newTonemapping.active = oldColorGrading.active; + + ConvertTonemapper(oldColorGrading.tonemapper, newTonemapping.mode, oldColorGrading.enabled); + + // White Balance + newWhiteBalance.active = oldColorGrading.active; + + oldColorGrading.temperature.Convert(newWhiteBalance.temperature, enabledState: oldColorGrading.enabled); + oldColorGrading.tint.Convert(newWhiteBalance.tint, enabledState: oldColorGrading.enabled); + + // Tone -> ColorAdjustments + newColorAdjustments.active = oldColorGrading.active; + + oldColorGrading.postExposure.Convert(newColorAdjustments.postExposure, + enabledState: oldColorGrading.enabled); + oldColorGrading.colorFilter.Convert(newColorAdjustments.colorFilter, oldColorGrading.enabled, + disabledColor: Color.white); + oldColorGrading.hueShift.Convert(newColorAdjustments.hueShift, enabledState: oldColorGrading.enabled); + oldColorGrading.saturation.Convert(newColorAdjustments.saturation, enabledState: oldColorGrading.enabled); + oldColorGrading.contrast.Convert(newColorAdjustments.contrast, enabledState: oldColorGrading.enabled); + + // Channel Mixer + newTargetProfile.active = oldColorGrading.active; + + oldColorGrading.mixerRedOutRedIn.Convert(newTargetProfile.redOutRedIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerRedOutGreenIn.Convert(newTargetProfile.redOutGreenIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerRedOutBlueIn.Convert(newTargetProfile.redOutBlueIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerGreenOutRedIn.Convert(newTargetProfile.greenOutRedIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerGreenOutGreenIn.Convert(newTargetProfile.greenOutGreenIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerGreenOutBlueIn.Convert(newTargetProfile.greenOutBlueIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerBlueOutRedIn.Convert(newTargetProfile.blueOutRedIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerBlueOutGreenIn.Convert(newTargetProfile.blueOutGreenIn, + enabledState: oldColorGrading.enabled); + oldColorGrading.mixerBlueOutBlueIn.Convert(newTargetProfile.blueOutBlueIn, + enabledState: oldColorGrading.enabled); + + // Trackballs -> LiftGammaGain + newLiftGammaGain.active = oldColorGrading.active; + + // Note: URP always does color grading in HDR values (as it should), + // which means the non-HDR modes no longer have valid conversion targets. + // So, these values are left at defaults (neutral) when not previously using HDR. + if (oldColorGrading.gradingMode.value == BIRPRendering.GradingMode.HighDefinitionRange) + { + oldColorGrading.lift.Convert(newLiftGammaGain.lift, oldColorGrading.enabled); + oldColorGrading.gamma.Convert(newLiftGammaGain.gamma, oldColorGrading.enabled); + oldColorGrading.gain.Convert(newLiftGammaGain.gain, oldColorGrading.enabled); + } + + // Grading Curves -> ColorCurves + newColorCurves.active = oldColorGrading.active; + + oldColorGrading.masterCurve.Convert(newColorCurves.master, oldColorGrading.enabled); + oldColorGrading.redCurve.Convert(newColorCurves.red, oldColorGrading.enabled); + oldColorGrading.greenCurve.Convert(newColorCurves.green, oldColorGrading.enabled); + oldColorGrading.blueCurve.Convert(newColorCurves.blue, oldColorGrading.enabled); + oldColorGrading.hueVsHueCurve.Convert(newColorCurves.hueVsHue, oldColorGrading.enabled); + oldColorGrading.hueVsSatCurve.Convert(newColorCurves.hueVsSat, oldColorGrading.enabled); + oldColorGrading.satVsSatCurve.Convert(newColorCurves.satVsSat, oldColorGrading.enabled); + oldColorGrading.lumVsSatCurve.Convert(newColorCurves.lumVsSat, oldColorGrading.enabled); + } + + private void ConvertTonemapper(BIRPRendering.TonemapperParameter birpSource, + URPRendering.TonemappingModeParameter target, bool enabledState) + { + if (target == null) return; + + switch (birpSource.value) + { + case BIRPRendering.Tonemapper.Neutral: + target.value = URPRendering.TonemappingMode.Neutral; + break; + case BIRPRendering.Tonemapper.ACES: + target.value = URPRendering.TonemappingMode.ACES; + break; + default: + target.value = URPRendering.TonemappingMode.None; + break; + } + + if (!enabledState) + { + target.value = URPRendering.TonemappingMode.None; + } + + target.overrideState = birpSource.overrideState; + } + } +} + +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/ColorGradingConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/ColorGradingConverter.cs.meta new file mode 100644 index 0000000..9a42707 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/ColorGradingConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c93687e52abd628448c8f7666b1dbd23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/DepthOfFieldConverter.cs b/Editor/Converter/PPv2/EffectConverters/DepthOfFieldConverter.cs new file mode 100644 index 0000000..d2b8a38 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/DepthOfFieldConverter.cs @@ -0,0 +1,38 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class DepthOfFieldConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.DepthOfField); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + var oldDepthOfField = oldSettings as BIRPRendering.DepthOfField; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldDepthOfField.active; + + // Always use Bokeh mode, because it has parity with the PPv2 approach + newVolumeComponent.mode.value = oldDepthOfField.enabled + ? URPRendering.DepthOfFieldMode.Bokeh + : URPRendering.DepthOfFieldMode.Off; + newVolumeComponent.mode.overrideState = true; + + oldDepthOfField.focusDistance.Convert(newVolumeComponent.focusDistance, enabledState: oldSettings.enabled); + oldDepthOfField.focalLength.Convert(newVolumeComponent.focalLength, enabledState: oldSettings.enabled); + oldDepthOfField.aperture.Convert(newVolumeComponent.aperture, enabledState: oldSettings.enabled); + + // TODO: No clear conversions for these? + // oldDepthOfField.kernelSize + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/DepthOfFieldConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/DepthOfFieldConverter.cs.meta new file mode 100644 index 0000000..e9b1a92 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/DepthOfFieldConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa79bbd82ff697846b2723bb624f5b5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/GrainConverter.cs b/Editor/Converter/PPv2/EffectConverters/GrainConverter.cs new file mode 100644 index 0000000..ff03666 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/GrainConverter.cs @@ -0,0 +1,42 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEditor; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class GrainConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.Grain); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + var oldGrain = oldSettings as BIRPRendering.Grain; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldGrain.active; + + oldGrain.intensity.Convert(newVolumeComponent.intensity, enabledState: oldGrain.enabled); + oldGrain.lumContrib.Convert(newVolumeComponent.response); + + newVolumeComponent.type.overrideState = oldGrain.size.overrideState; + if (oldGrain.size.value > 1.5f) + newVolumeComponent.type.value = URPRendering.FilmGrainLookup.Medium3; + else if (oldGrain.size.value > 1.25f) + newVolumeComponent.type.value = URPRendering.FilmGrainLookup.Medium2; + else if (oldGrain.size.value > 0.7f) + newVolumeComponent.type.value = URPRendering.FilmGrainLookup.Thin2; + else + newVolumeComponent.type.value = URPRendering.FilmGrainLookup.Thin1; + + // TODO: No clear conversions for these? + // oldGrain.colored + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/GrainConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/GrainConverter.cs.meta new file mode 100644 index 0000000..4a794a6 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/GrainConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df39fb04691e914469d4b4ae2a027fb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/LensDistortionConverter.cs b/Editor/Converter/PPv2/EffectConverters/LensDistortionConverter.cs new file mode 100644 index 0000000..ac10b54 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/LensDistortionConverter.cs @@ -0,0 +1,39 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class LensDistortionConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.LensDistortion); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + var oldLensDistortion = oldSettings as BIRPRendering.LensDistortion; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldLensDistortion.active; + + oldLensDistortion.intensity.Convert(newVolumeComponent.intensity, + scale: 0.01f, + enabledState: oldLensDistortion.enabled); + oldLensDistortion.intensityX.Convert(newVolumeComponent.xMultiplier); + oldLensDistortion.intensityY.Convert(newVolumeComponent.yMultiplier); + oldLensDistortion.scale.Convert(newVolumeComponent.scale); + + newVolumeComponent.center.overrideState = + oldLensDistortion.centerX.overrideState || oldLensDistortion.centerY.overrideState; + newVolumeComponent.center.value = + new Vector2(oldLensDistortion.centerX.value, oldLensDistortion.centerY.value); + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/LensDistortionConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/LensDistortionConverter.cs.meta new file mode 100644 index 0000000..75166bf --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/LensDistortionConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef0ef98463379a649ba68d026c95ea4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/MotionBlurConverter.cs b/Editor/Converter/PPv2/EffectConverters/MotionBlurConverter.cs new file mode 100644 index 0000000..3cb17a6 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/MotionBlurConverter.cs @@ -0,0 +1,37 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEditor; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class MotionBlurConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.MotionBlur); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, VolumeProfile targetProfile) + { + var oldMotionBlur = oldSettings as BIRPRendering.MotionBlur; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldMotionBlur.active; + + // Note: These settings cannot provide visual parity, + // but this scale factor provides a good starting point. + oldMotionBlur.shutterAngle.Convert(newVolumeComponent.intensity, scale: 1f / 360f, oldMotionBlur.enabled); + + newVolumeComponent.quality.overrideState = oldMotionBlur.sampleCount.overrideState; + if (oldMotionBlur.sampleCount >= 24) + newVolumeComponent.quality.value = URPRendering.MotionBlurQuality.High; + else if (oldMotionBlur.sampleCount > 12) + newVolumeComponent.quality.value = URPRendering.MotionBlurQuality.Medium; + else + newVolumeComponent.quality.value = URPRendering.MotionBlurQuality.Low; + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/MotionBlurConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/MotionBlurConverter.cs.meta new file mode 100644 index 0000000..cf9d3e5 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/MotionBlurConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d1c67b3de6d65a44b641566a9d529b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/PostProcessEffectSettingsConverter.cs b/Editor/Converter/PPv2/EffectConverters/PostProcessEffectSettingsConverter.cs new file mode 100644 index 0000000..e80d1a6 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/PostProcessEffectSettingsConverter.cs @@ -0,0 +1,43 @@ +#if PPV2_EXISTS +using System; +using UnityEditor; +using UnityEngine; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public abstract class PostProcessEffectSettingsConverter : ScriptableObject + { + protected abstract Type OldSettingsType { get; } + + public void AddConvertedProfileSettingsToProfile( + BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + if (oldSettings == null || oldSettings.GetType() != OldSettingsType) return; + if (targetProfile == null || targetProfile.Has(OldSettingsType)) return; + + ConvertToTarget(oldSettings, targetProfile); + } + + protected abstract void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldBloom, + VolumeProfile targetProfile); + + protected T AddVolumeComponentToAsset(VolumeProfile targetProfileAsset) where T : VolumeComponent + { + if (!targetProfileAsset) return null; + + var profilePath = AssetDatabase.GetAssetPath(targetProfileAsset); + + if (string.IsNullOrEmpty(profilePath)) return null; + + var newVolumeComponent = targetProfileAsset.Add(); + AssetDatabase.AddObjectToAsset(newVolumeComponent, targetProfileAsset); + + return newVolumeComponent; + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/PostProcessEffectSettingsConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/PostProcessEffectSettingsConverter.cs.meta new file mode 100644 index 0000000..664fb65 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/PostProcessEffectSettingsConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fce1ffd6e78acfd4aa944af71b8a07d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/PropertyConversions.cs b/Editor/Converter/PPv2/EffectConverters/PropertyConversions.cs new file mode 100644 index 0000000..3dce1e7 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/PropertyConversions.cs @@ -0,0 +1,93 @@ +#if PPV2_EXISTS +using System.Data; +using UnityEngine; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; + +namespace BIRPToURPConversionExtensions +{ + public static class PropertyConversions + { + public static void Convert(this BIRPRendering.FloatParameter birpSource, FloatParameter target, float scale = 1f, bool enabledState = true) + { + if (target == null) return; + + target.value = enabledState ? birpSource.value * scale : 0f; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.FloatParameter birpSource, MinFloatParameter target, float scale = 1f, bool enabledState = true) + { + if (target == null) return; + + target.value = enabledState ? birpSource.value * scale : 0f; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.FloatParameter birpSource, ClampedFloatParameter target, float scale = 1f, bool enabledState = true) + { + if (target == null) return; + + target.value = enabledState ? birpSource.value * scale : 0f; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.Vector2Parameter birpSource, Vector2Parameter target) + { + if (target == null) return; + + target.value = birpSource.value; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.Vector4Parameter birpSource, Vector4Parameter target, bool enabledState = true) + { + if (target == null) return; + + target.value = enabledState ? birpSource.value : new Vector4(1f, 1f, 1f, 0f); + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.ColorParameter birpSource, ColorParameter target, bool enabledState, Color disabledColor) + { + if (target == null) return; + + target.value = enabledState ? birpSource.value : disabledColor; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.ColorParameter birpSource, ColorParameter target) + { + if (target == null) return; + + target.value = birpSource.value; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.TextureParameter birpSource, TextureParameter target) + { + if (target == null) return; + + target.value = birpSource.value; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.BoolParameter birpSource, BoolParameter target, bool invertValue = false) + { + if (target == null) return; + + target.value = invertValue ? !birpSource.value : birpSource.value; + target.overrideState = birpSource.overrideState; + } + + public static void Convert(this BIRPRendering.SplineParameter birpSource, TextureCurveParameter target, bool enabledState = true) + { + if (target == null) return; + + target.value = new TextureCurve(birpSource.value.curve, zeroValue: 0f, loop: false, Vector2.up); + + target.overrideState = birpSource.overrideState; + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/PropertyConversions.cs.meta b/Editor/Converter/PPv2/EffectConverters/PropertyConversions.cs.meta new file mode 100644 index 0000000..dfd5e2b --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/PropertyConversions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55392cd2a34cb21499958e42eba26b2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/EffectConverters/VignetteConverter.cs b/Editor/Converter/PPv2/EffectConverters/VignetteConverter.cs new file mode 100644 index 0000000..0cde643 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/VignetteConverter.cs @@ -0,0 +1,47 @@ +#if PPV2_EXISTS +using System; +using BIRPToURPConversionExtensions; +using UnityEngine.Rendering; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + public class VignetteConverter : PostProcessEffectSettingsConverter + { + protected override Type OldSettingsType { get; } = typeof(BIRPRendering.Vignette); + + protected override void ConvertToTarget(BIRPRendering.PostProcessEffectSettings oldSettings, + VolumeProfile targetProfile) + { + var oldVignette = oldSettings as BIRPRendering.Vignette; + + var newVolumeComponent = AddVolumeComponentToAsset(targetProfile); + + newVolumeComponent.active = oldVignette.active; + + oldVignette.color.Convert(newVolumeComponent.color); + + if (oldVignette.mode.value == BIRPRendering.VignetteMode.Masked) + { + // There's not much we can do with the Masked mode at present, + // so we just assume the old opacity should be used as intensity, + // and leave all other settings at default values. + oldVignette.opacity.Convert(newVolumeComponent.intensity, enabledState: oldSettings.enabled); + } + else + { + oldVignette.intensity.Convert(newVolumeComponent.intensity, enabledState: oldSettings.enabled); + + oldVignette.center.Convert(newVolumeComponent.center); + oldVignette.rounded.Convert(newVolumeComponent.rounded); + oldVignette.smoothness.Convert(newVolumeComponent.smoothness); + } + + // TODO: No clear conversions for these? + // oldVignette.mask + // oldVignette.roundness + } + } +} +#endif diff --git a/Editor/Converter/PPv2/EffectConverters/VignetteConverter.cs.meta b/Editor/Converter/PPv2/EffectConverters/VignetteConverter.cs.meta new file mode 100644 index 0000000..4a4ded7 --- /dev/null +++ b/Editor/Converter/PPv2/EffectConverters/VignetteConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de573be7419f3b84295377f64cf664c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/PPv2ConversionIndexers.cs b/Editor/Converter/PPv2/PPv2ConversionIndexers.cs new file mode 100644 index 0000000..50de0e2 --- /dev/null +++ b/Editor/Converter/PPv2/PPv2ConversionIndexers.cs @@ -0,0 +1,37 @@ +#if PPV2_EXISTS +using UnityEditor.Search; +using UnityEngine; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; + +namespace UnityEditor.Rendering.Universal.Converters +{ + static class PPv2ConversionIndexers + { + // Note: Iterating this version number does not force an index rebuild. + // If modifying this code, you will need to either delete the Library directory, + // or open "Window > Search > Index Manager" and right-click each indexer to do a Force Rebuild. + private const int Version = 10; + + [CustomObjectIndexer(typeof(Object), version = Version)] + internal static void ConversionIndexer(CustomObjectIndexerTarget context, ObjectIndexer indexer) + { + // Note: Volumes and Layers on the same object would still produce only a + // single result in the "urp:convert-ppv2component" search, thus we only + // explicitly add one or the other here, instead of both. + if (context.targetType == typeof(BIRPRendering.PostProcessVolume)) + { + indexer.AddProperty("urp", "convert-ppv2component", context.documentIndex); + } + else if (context.targetType == typeof(BIRPRendering.PostProcessLayer)) + { + indexer.AddProperty("urp", "convert-ppv2component", context.documentIndex); + } + + if (context.targetType == typeof(BIRPRendering.PostProcessProfile)) + { + indexer.AddProperty("urp", "convert-ppv2scriptableobject", context.documentIndex); + } + } + } +} +#endif diff --git a/Editor/Converter/PPv2/PPv2ConversionIndexers.cs.meta b/Editor/Converter/PPv2/PPv2ConversionIndexers.cs.meta new file mode 100644 index 0000000..8176098 --- /dev/null +++ b/Editor/Converter/PPv2/PPv2ConversionIndexers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 89952a5e365cbf54699031f6ee002f48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/PPv2Converter.cs b/Editor/Converter/PPv2/PPv2Converter.cs new file mode 100644 index 0000000..3bd2b31 --- /dev/null +++ b/Editor/Converter/PPv2/PPv2Converter.cs @@ -0,0 +1,607 @@ +#if PPV2_EXISTS +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using UnityEditor; +using UnityEditor.Rendering; +using UnityEditor.SceneManagement; +using UnityEditor.Search; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; +using UnityEngine.SceneManagement; +using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using Object = UnityEngine.Object; +using URPRenderingEditor = UnityEditor.Rendering.Universal; +using URPRendering = UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.Converters +{ + internal class PPv2Converter : RenderPipelineConverter + { + public override string name => "Post-Processing Stack v2 Converter"; + public override string info => + "Converts PPv2 Volumes, Profiles, and Layers to URP Volumes, Profiles, and Cameras."; + public override Type container => typeof(BuiltInToURPConverterContainer); + public override bool needsIndexing => true; + + private IEnumerable effectConverters = null; + + private List postConversionDestroyables = null; + + List guids = new List(); + public override void OnInitialize(InitializeConverterContext context, Action callback) + { + // Converters should already be set to null on domain reload, + // but we're doing it here just in case anything somehow lingers. + effectConverters = null; + + postConversionDestroyables = new List(); + + // We are using separate searchContexts here and Adding them in this order: + // - Components from Prefabs & Scenes (Volumes & Layers) + // - ScriptableObjects (Profiles) + // + // This allows the old objects to be both re-referenced and deleted safely as they are converted in OnRun. + // The process of converting Volumes will convert Profiles as-needed, and then the explicit followup Profile + // conversion step will convert any non-referenced assets and delete all old Profiles. + Debug.Log("Running here"); + // Components First + using var componentContext = + Search.SearchService.CreateContext("asset", "urp:convert-ppv2component"); + using var componentItems = Search.SearchService.Request(componentContext); + { + Debug.Log("First Search"); + AddSearchItemsAsConverterAssetEntries(componentItems, context); + } + + // Then ScriptableObjects + using var scriptableObjectContext = + Search.SearchService.CreateContext("asset", "urp:convert-ppv2scriptableobject"); + using var scriptableObjectItems = Search.SearchService.Request(scriptableObjectContext); + { + Debug.Log("Second Search"); + AddSearchItemsAsConverterAssetEntries(scriptableObjectItems, context); + } + + callback.Invoke(); + } + + public override void OnRun(ref RunItemContext context) + { + var obj = GetContextObject(ref context); + + if (!obj) + { + context.didFail = true; + context.info = "Could not be converted because the target object was lost."; + return; + } + + BIRPRendering.PostProcessVolume[] oldVolumes = null; + BIRPRendering.PostProcessLayer[] oldLayers = null; + + // TODO: Upcoming changes to GlobalObjectIdentifierToObjectSlow will allow + // this to be inverted, and the else to be deleted. +#if false + if (obj is GameObject go) + { + oldVolumes = go.GetComponents(); + oldLayers = go.GetComponents(); + } + else if (obj is MonoBehaviour mb) + { + oldVolumes = mb.GetComponents(); + oldLayers = mb.GetComponents(); + } +#else + if (obj is GameObject go) + { + oldVolumes = go.GetComponentsInChildren(); + oldLayers = go.GetComponentsInChildren(); + } + else if (obj is MonoBehaviour mb) + { + oldVolumes = mb.GetComponentsInChildren(); + oldLayers = mb.GetComponentsInChildren(); + } +#endif + + // Note: even if nothing needs to be converted, that should still count as success, + // though it shouldn't ever actually occur. + var succeeded = true; + var errorString = new StringBuilder(); + + if (effectConverters == null || + effectConverters.Count() == 0 || + effectConverters.Any(converter => converter == null)) + { + effectConverters = GetAllBIRPConverters(); + } + + if (oldVolumes != null) + { + foreach (var oldVolume in oldVolumes) + { + ConvertVolume(oldVolume, ref succeeded, errorString); + } + } + + if (oldLayers != null) + { + foreach (var oldLayer in oldLayers) + { + ConvertLayer(oldLayer, ref succeeded, errorString); + } + } + + if (obj is BIRPRendering.PostProcessProfile oldProfile) + { + ConvertProfile(oldProfile, ref succeeded, errorString); + } + + if (!succeeded) + { + context.didFail = true; + context.info = errorString.ToString(); + } + else + { + var currentScene = SceneManager.GetActiveScene(); + EditorSceneManager.SaveScene(currentScene); + } + } + + public override void OnPostRun() + { + for (var i = 0; i < postConversionDestroyables.Count; i++) + { + Object.DestroyImmediate(postConversionDestroyables[i], allowDestroyingAssets: true); + } + + postConversionDestroyables.Clear(); + } + + public override void OnClicked(int index) + { + if (GlobalObjectId.TryParse(guids[index], out var gid)) + { + var containerPath = AssetDatabase.GUIDToAssetPath(gid.assetGUID); + EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(containerPath)); + } + } + + private void AddSearchItemsAsConverterAssetEntries(ISearchList searchItems, InitializeConverterContext context) + { + foreach (var searchItem in searchItems) + { + if (searchItem == null || !GlobalObjectId.TryParse(searchItem.id, out var globalId)) + { + continue; + } + + var description = searchItem.provider.fetchDescription(searchItem, searchItem.context); + + var item = new ConverterItemDescriptor() + { + name = description.Split('/').Last().Split('.').First(), + info = $"{ReturnType(globalId)}", + }; + + guids.Add(globalId.ToString()); + context.AddAssetToConvert(item); + } + } + + string ReturnType(GlobalObjectId gid) + { + var containerPath = AssetDatabase.GUIDToAssetPath(gid.assetGUID); + return AssetDatabase.LoadAssetAtPath(containerPath).GetType().ToString().Split('.').Last(); + } + + private Object GetContextObject(ref RunItemContext ctx) + { + var item = ctx.item; + var guid = guids[item.index]; + + if (GlobalObjectId.TryParse(guid, out var globalId)) + { + // Try loading the object + // TODO: Upcoming changes to GlobalObjectIdentifierToObjectSlow will allow it + // to return direct references to prefabs and their children. + // Once that change happens there are several items which should be adjusted. + var obj = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(globalId); + + // If the object was not loaded, it is probably part of an unopened scene; + // if so, then the solution is to first load the scene here. + var objIsInSceneOrPrefab = globalId.identifierType == 2; // 2 is IdentifierType.kSceneObject + if (!obj && + objIsInSceneOrPrefab) + { + // Open the Containing Scene Asset in the Hierarchy so the Object can be manipulated + var mainAssetPath = AssetDatabase.GUIDToAssetPath(globalId.assetGUID); + var mainAsset = AssetDatabase.LoadAssetAtPath(mainAssetPath); + AssetDatabase.OpenAsset(mainAsset); + + // If a prefab stage was opened, then mainAsset is the root of the + // prefab that contains the target object, so reference that for now, + // until GlobalObjectIdentifierToObjectSlow is updated + if (PrefabStageUtility.GetCurrentPrefabStage() != null) + { + obj = mainAsset; + } + + // Reload object if it is still null (because it's in a previously unopened scene) + if (!obj) + { + obj = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(globalId); + if (!obj) + { + ctx.didFail = true; + ctx.info = $"Object {globalId.assetGUID} failed to load..."; + } + } + } + + return obj; + } + + ctx.didFail = true; + ctx.info = $"Failed to parse Global ID {item.descriptor.info}..."; + + return null; + } + +#region Conversion_Entry_Points + + private void ConvertVolume(BIRPRendering.PostProcessVolume oldVolume, ref bool succeeded, + StringBuilder errorString) + { + if (!succeeded) + { + return; + } + + if (!oldVolume) + { + // TODO: unless there's good way to tell the if the object is just missing because it was already + // converted as part of an earlier conversion object, then these two lines should be commented + // out or removed. It should still return though. + // succeeded = false; + // errorString.AppendLine("PPv2 PostProcessVolume failed to be converted because the original asset reference was lost during conversion."); + return; + } + + if (PrefabUtility.IsPartOfPrefabInstance(oldVolume) && + !PrefabUtility.IsAddedComponentOverride(oldVolume)) + { + // This is a property override on an instance of the component, + // so override the component instance with the modifications. + succeeded = ConvertVolumeInstance(oldVolume, errorString); + } + else + { + // The entire component is unique, so just convert it + succeeded = ConvertVolumeComponent(oldVolume, errorString); + } + } + + private void ConvertLayer(BIRPRendering.PostProcessLayer oldLayer, ref bool succeeded, + StringBuilder errorString) + { + if (!succeeded) + { + return; + } + + if (!oldLayer) + { + // TODO: unless there's good way to tell the if the object is just missing because it was already + // converted as part of an earlier conversion object, then these two lines should be commented + // out or removed. It should still return though. + // succeeded = false; + // errorString.AppendLine("PPv2 PostProcessLayer failed to be converted because the original asset reference was lost during conversion."); + return; + } + + if (PrefabUtility.IsPartOfPrefabInstance(oldLayer) && + !PrefabUtility.IsAddedComponentOverride(oldLayer)) + { + // This is a property override on an instance of the component, + // so override the component instance with the modifications. + succeeded = ConvertLayerInstance(oldLayer, errorString); + } + else + { + // The entire component is unique, so just convert it + succeeded = ConvertLayerComponent(oldLayer, errorString); + } + } + + private void ConvertProfile(BIRPRendering.PostProcessProfile oldProfile, ref bool succeeded, + StringBuilder errorString) + { + if (!succeeded) + { + return; + } + + if (!oldProfile) + { + errorString.AppendLine( + "PPv2 PostProcessProfile failed to be converted because the original asset reference was lost during conversion."); + return; + } + + ConvertVolumeProfileAsset(oldProfile, errorString, ref succeeded); + + // TODO: + // - Perhaps old Profiles should only be deleted if they actually no longer have references, + // just in case some some Volume conversions are skipped and still need references for future conversion. + // - Alternatively, leave deletion of Profiles entirely to the user. (I think this is preferred) + } + +#endregion Conversion_Entry_Points + + private bool ConvertVolumeComponent(BIRPRendering.PostProcessVolume oldVolume, StringBuilder errorString) + { + // Don't convert if it appears to already have been converted. + if (oldVolume.GetComponent()) return true; + + var gameObject = oldVolume.gameObject; + var newVolume = gameObject.AddComponent(); + + newVolume.priority = oldVolume.priority; + newVolume.weight = oldVolume.weight; + newVolume.blendDistance = oldVolume.blendDistance; + newVolume.isGlobal = oldVolume.isGlobal; + newVolume.enabled = oldVolume.enabled; + + var success = true; + newVolume.sharedProfile = ConvertVolumeProfileAsset(oldVolume.sharedProfile, errorString, ref success); + + if (PrefabUtility.IsPartOfPrefabAsset(oldVolume)) + { + postConversionDestroyables.Add(oldVolume); + } + else + { + Object.DestroyImmediate(oldVolume, allowDestroyingAssets: true); + } + + EditorUtility.SetDirty(gameObject); + + return success; + } + + private bool ConvertVolumeInstance(BIRPRendering.PostProcessVolume oldVolume, StringBuilder errorString) + { + // First get a reference to the local instance of the converted component + // which may require immediately converting it at its origin location first. + var newVolumeInstance = oldVolume.GetComponent(); + if (!newVolumeInstance) + { + var oldVolumeOrigin = PrefabUtility.GetCorrespondingObjectFromSource(oldVolume); + + if (!ConvertVolumeComponent(oldVolumeOrigin, errorString)) + { + return false; + } + + PrefabUtility.SavePrefabAsset(oldVolumeOrigin.gameObject); + + newVolumeInstance = oldVolume.GetComponent(); + + if (!newVolumeInstance) + { + errorString.AppendLine( + "PPv2 PostProcessVolume failed to be converted because the instance object did not inherit the converted Prefab source."); + return false; + } + } + + bool success = true; + var oldModifications = PrefabUtility.GetPropertyModifications(oldVolume); + foreach (var oldModification in oldModifications) + { + if (oldModification.target is BIRPRendering.PostProcessVolume) + { + if (oldModification.propertyPath.EndsWith("priority", StringComparison.InvariantCultureIgnoreCase)) + newVolumeInstance.priority = oldVolume.priority; + else if (oldModification.propertyPath.EndsWith("weight", + StringComparison.InvariantCultureIgnoreCase)) + newVolumeInstance.weight = oldVolume.weight; + else if (oldModification.propertyPath.EndsWith("blendDistance", + StringComparison.InvariantCultureIgnoreCase)) + newVolumeInstance.blendDistance = oldVolume.blendDistance; + else if (oldModification.propertyPath.EndsWith("isGlobal", + StringComparison.InvariantCultureIgnoreCase)) + newVolumeInstance.isGlobal = oldVolume.isGlobal; + else if (oldModification.propertyPath.EndsWith("enabled", + StringComparison.InvariantCultureIgnoreCase)) + newVolumeInstance.enabled = oldVolume.enabled; + else if (oldModification.propertyPath.EndsWith("sharedProfile", + StringComparison.InvariantCultureIgnoreCase)) + newVolumeInstance.sharedProfile = + ConvertVolumeProfileAsset(oldVolume.sharedProfile, errorString, ref success); + + EditorUtility.SetDirty(newVolumeInstance); + } + } + + return success; + } + + private bool ConvertLayerComponent(BIRPRendering.PostProcessLayer oldLayer, StringBuilder errorString) + { + var siblingCamera = oldLayer.GetComponent().GetUniversalAdditionalCameraData(); + + // PostProcessLayer requires a sibling Camera component, but + // we check it here just in case something weird went happened. + if (!siblingCamera) + { + errorString.AppendLine( + "PPv2 PostProcessLayer failed to be converted because the instance object was missing a required sibling Camera component."); + return false; + } + + // The presence of a PostProcessLayer implies the Camera should render post-processes + siblingCamera.renderPostProcessing = true; + + siblingCamera.volumeLayerMask = oldLayer.volumeLayer; + siblingCamera.volumeTrigger = oldLayer.volumeTrigger; + siblingCamera.stopNaN = oldLayer.stopNaNPropagation; + + siblingCamera.antialiasingQuality = + (URPRendering.AntialiasingQuality)oldLayer.subpixelMorphologicalAntialiasing.quality; + + switch (oldLayer.antialiasingMode) + { + case BIRPRendering.PostProcessLayer.Antialiasing.None: + siblingCamera.antialiasing = URPRendering.AntialiasingMode.None; + break; + case BIRPRendering.PostProcessLayer.Antialiasing.FastApproximateAntialiasing: + siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; + break; + case BIRPRendering.PostProcessLayer.Antialiasing.SubpixelMorphologicalAntialiasing: + siblingCamera.antialiasing = URPRendering.AntialiasingMode.SubpixelMorphologicalAntiAliasing; + break; + default: + // Default to the the most performant mode, since "None" is an explicit option. + siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; + break; + } + + if (PrefabUtility.IsPartOfPrefabAsset(oldLayer)) + { + postConversionDestroyables.Add(oldLayer); + } + else + { + Object.DestroyImmediate(oldLayer, allowDestroyingAssets: true); + } + + EditorUtility.SetDirty(siblingCamera.gameObject); + + return true; + } + + private bool ConvertLayerInstance(BIRPRendering.PostProcessLayer oldLayer, StringBuilder errorString) + { + // First get a reference to the local instance of the camera (which is required by PostProcessingLayer) + var siblingCamera = oldLayer.GetComponent().GetUniversalAdditionalCameraData(); + if (!siblingCamera) + { + errorString.AppendLine( + "PPv2 PostProcessLayer failed to be converted because the instance object was missing a required sibling Camera component."); + return false; + } + + var oldModifications = PrefabUtility.GetPropertyModifications(oldLayer); + foreach (var oldModification in oldModifications) + { + if (oldModification.target is BIRPRendering.PostProcessLayer) + { + if (oldModification.propertyPath.EndsWith("volumeLayer", + StringComparison.InvariantCultureIgnoreCase)) + siblingCamera.volumeLayerMask = oldLayer.volumeLayer; + else if (oldModification.propertyPath.EndsWith("volumeTrigger", + StringComparison.InvariantCultureIgnoreCase)) + siblingCamera.volumeTrigger = oldLayer.volumeTrigger; + else if (oldModification.propertyPath.EndsWith("stopNaNPropagation", + StringComparison.InvariantCultureIgnoreCase)) + siblingCamera.stopNaN = oldLayer.stopNaNPropagation; + else if (oldModification.propertyPath.EndsWith("quality", + StringComparison.InvariantCultureIgnoreCase)) + siblingCamera.antialiasingQuality = + (URPRendering.AntialiasingQuality)oldLayer.subpixelMorphologicalAntialiasing.quality; + else if (oldModification.propertyPath.EndsWith("antialiasingMode", + StringComparison.InvariantCultureIgnoreCase)) + { + switch (oldLayer.antialiasingMode) + { + case BIRPRendering.PostProcessLayer.Antialiasing.None: + siblingCamera.antialiasing = URPRendering.AntialiasingMode.None; + break; + case BIRPRendering.PostProcessLayer.Antialiasing.FastApproximateAntialiasing: + siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; + break; + case BIRPRendering.PostProcessLayer.Antialiasing.SubpixelMorphologicalAntialiasing: + siblingCamera.antialiasing = + URPRendering.AntialiasingMode.SubpixelMorphologicalAntiAliasing; + break; + default: + // Default to the the most performant mode, since "None" is an explicit option. + siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; + break; + } + } + + EditorUtility.SetDirty(siblingCamera); + } + } + + return true; + } + + private VolumeProfile ConvertVolumeProfileAsset(BIRPRendering.PostProcessProfile oldProfile, + StringBuilder errorString, ref bool success) + { + // Don't convert if it appears to already have been converted. + if (!oldProfile) return null; + + var oldPath = AssetDatabase.GetAssetPath(oldProfile); + var oldDirectory = Path.GetDirectoryName(oldPath); + var oldName = Path.GetFileNameWithoutExtension(oldPath); + var newPath = Path.Combine(oldDirectory, $"{oldName}(URP).asset"); + if (File.Exists(newPath)) + { + return AssetDatabase.LoadAssetAtPath(newPath); + } + + var newProfile = ScriptableObject.CreateInstance(); + try + { + AssetDatabase.CreateAsset(newProfile, newPath); + } + catch (Exception e) + { + errorString.AppendLine($"PPv2 PostProcessLayer failed to be converted with exception:\n{e}"); + success = false; + + if (!newProfile) return null; + } + + foreach (var oldSettings in oldProfile.settings) + { + foreach (var effectConverter in effectConverters) + { + effectConverter.AddConvertedProfileSettingsToProfile(oldSettings, newProfile); + } + } + + EditorUtility.SetDirty(newProfile); + + return newProfile; + } + + public IEnumerable GetAllBIRPConverters() + { + var baseType = typeof(PostProcessEffectSettingsConverter); + + var assembly = Assembly.GetAssembly(baseType); + var derivedTypes = assembly + .GetTypes() + .Where(t => + t.BaseType != null && + t.BaseType == baseType) + .Select(t => ScriptableObject.CreateInstance(t) as PostProcessEffectSettingsConverter); + + return derivedTypes; + } + } +} +#endif diff --git a/Editor/Converter/PPv2/PPv2Converter.cs.meta b/Editor/Converter/PPv2/PPv2Converter.cs.meta new file mode 100644 index 0000000..2391c24 --- /dev/null +++ b/Editor/Converter/PPv2/PPv2Converter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54019ac30a4ca724eac51bad54f48aac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/PPv2/PPv2ToURPConvertersDefinition.asmdef b/Editor/Converter/PPv2/PPv2ToURPConvertersDefinition.asmdef new file mode 100644 index 0000000..386bad6 --- /dev/null +++ b/Editor/Converter/PPv2/PPv2ToURPConvertersDefinition.asmdef @@ -0,0 +1,29 @@ +{ + "name": "PPv2URPConverters", + "rootNamespace": "", + "references": [ + "GUID:c579267770062bf448e75eb160330b7f", + "GUID:a35efad8797223d499f8c68b1f545dbc", + "GUID:15fc0a57446b3144c949da3e2b9737a9", + "GUID:d60799ab2a985554ea1a39cd38695018", + "GUID:3eae0364be2026648bf74846acb8a731", + "GUID:df380645f10b7bc4b97d4f5eb6303d95" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.postprocessing", + "expression": "0.0.1", + "define": "PPV2_EXISTS" + } + ], + "noEngineReferences": false +} diff --git a/Editor/Converter/PPv2/PPv2ToURPConvertersDefinition.asmdef.meta b/Editor/Converter/PPv2/PPv2ToURPConvertersDefinition.asmdef.meta new file mode 100644 index 0000000..8427bfd --- /dev/null +++ b/Editor/Converter/PPv2/PPv2ToURPConvertersDefinition.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3fa284cf2189b184e8d506b83da68377 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/ReadonlyMaterialConverter.cs b/Editor/Converter/ReadonlyMaterialConverter.cs new file mode 100644 index 0000000..7ff3fd3 --- /dev/null +++ b/Editor/Converter/ReadonlyMaterialConverter.cs @@ -0,0 +1,295 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; +using Object = UnityEngine.Object; + +namespace UnityEditor.Rendering.Universal.Converters +{ + enum IdentifierType { kNullIdentifier = 0, kImportedAsset = 1, kSceneObject = 2, kSourceAsset = 3, kBuiltInAsset = 4 }; + + internal static class ReadonlyMaterialMap + { + public static readonly Dictionary Map = new Dictionary + { + {"Default-Diffuse", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat"}, + {"Default-Material", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat"}, + {"Default-ParticleSystem", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/ParticlesUnlit.mat"}, + {"Default-Particle", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/ParticlesUnlit.mat"}, + {"Default-Terrain-Diffuse", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/TerrainLit.mat"}, + {"Default-Terrain-Specular", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/TerrainLit.mat"}, + {"Default-Terrain-Standard", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/TerrainLit.mat"}, + {"Sprites-Default", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Sprite-Unlit-Default.mat"}, + {"Sprites-Mask", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Sprite-Unlit-Default.mat"}, + {"SpatialMappingOcclusion", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/SpatialMappingOcclusion.mat"}, + {"SpatialMappingWireframe", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/SpatialMappingWireframe.mat"}, + + // TODO: These currently render in URP, but they are using BIRP shaders. Create a task to convert these. + // {"Default UI Material", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat"}, + // {"ETC1 Supported UI Material", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat"}, + // {"Default-Line", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat"}, + // {"Default-Skybox", "Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat"}, + }; + } + + internal class ReadonlyMaterialConverter : RenderPipelineConverter + { + public override string name => "Readonly Material Converter"; + public override string info => "Converts references to Built-In readonly materials to URP readonly materials. This will create temporarily a .index file and that can take a long time."; + public override Type container => typeof(BuiltInToURPConverterContainer); + public override bool needsIndexing => true; + + List guids = new List(); + + public override void OnInitialize(InitializeConverterContext ctx, Action callback) + { + var context = Search.SearchService.CreateContext("asset", "urp:convert-readonly"); + + Search.SearchService.Request(context, (c, items) => + { + // we're going to do this step twice in order to get them ordered, but it should be fast + var orderedRequest = items.OrderBy(req => + { + GlobalObjectId.TryParse(req.id, out var gid); + return gid.assetGUID; + }); + + foreach (var r in orderedRequest) + { + if (r == null || !GlobalObjectId.TryParse(r.id, out var gid)) + { + continue; + } + + var label = r.provider.fetchLabel(r, r.context); + var description = r.provider.fetchDescription(r, r.context); + + var item = new ConverterItemDescriptor() + { + name = description.Split('/').Last().Split('.').First(), + info = $"{label}", + }; + guids.Add(gid.ToString()); + + ctx.AddAssetToConvert(item); + } + + callback.Invoke(); + }); + context?.Dispose(); + } + + public override void OnRun(ref RunItemContext ctx) + { + var obj = LoadObject(ref ctx); + var result = true; + var errorString = new StringBuilder(); + + if (obj != null) + { + var materials = MaterialReferenceBuilder.GetMaterialsFromObject(obj); + + foreach (var material in materials) + { + if (material == null) + { + continue; + } + // there might be multiple materials on this object, we only care about the ones we explicitly try to remap that fail + if (!MaterialReferenceBuilder.GetIsReadonlyMaterial(material)) continue; + if (!ReadonlyMaterialMap.Map.ContainsKey(material.name)) continue; + if (!ReassignMaterial(obj, material.name, ReadonlyMaterialMap.Map[material.name])) + { + result = false; + errorString.AppendLine($"Material {material.name} failed to be reassigned"); + } + } + } + else + { + result = false; + errorString.AppendLine($"Object {ctx.item.descriptor.name} could not be loaded"); + } + + if (!result) + { + ctx.didFail = true; + ctx.info = errorString.ToString(); + } + else + { + // make sure the changes get saved + EditorUtility.SetDirty(obj); + var currentScene = SceneManager.GetActiveScene(); + EditorSceneManager.SaveScene(currentScene); + } + } + + public override void OnClicked(int index) + { + if (GlobalObjectId.TryParse(guids[index], out var gid)) + { + var containerPath = AssetDatabase.GUIDToAssetPath(gid.assetGUID); + EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(containerPath)); + } + } + + private static bool ReassignMaterial(Object obj, string oldMaterialName, string newMaterialPath) + { + var result = true; + + // do the reflection to make sure we get the right material reference + if (obj is GameObject go) + { + foreach (var key in MaterialReferenceBuilder.GetComponentTypes()) + { + var components = go.GetComponentsInChildren(key); + foreach (var component in components) + { + result &= ReassignMaterialOnComponentOrObject(component, + oldMaterialName, + newMaterialPath); + } + } + } + else + { + result &= ReassignMaterialOnComponentOrObject(obj, + oldMaterialName, + newMaterialPath); + } + + return result; + } + + private static bool ReassignMaterialOnComponentOrObject(Object obj, + string oldMaterialName, + string newMaterialPath) + { + var result = true; + + var materialProperties = obj.GetType().GetMaterialPropertiesWithoutLeaking(); + + foreach (var property in materialProperties) + { + var materialValue = property.GetGetMethod().GetMaterialFromMethod(obj, (methodName, objectName) => + $"The method {methodName} was not found on {objectName}. Ignoring this property."); + + if (materialValue is Material material) + { + if (material.name.Equals(oldMaterialName, StringComparison.OrdinalIgnoreCase)) + { + var newMaterial = AssetDatabase.LoadAssetAtPath(newMaterialPath); + + if (newMaterial != null) + { + var setMethod = property.GetSetMethod(); + if (setMethod != null) + { + setMethod.Invoke(obj, new object[] { newMaterial }); + } + else + { + // failed to set the material from the SetMethod + result = false; + } + } + else + { + // a material we expected to exist does not + result = false; + } + } + } + else if (materialValue is Material[] materialList) + { + for (int i = 0; i < materialList.Length; i++) + { + var mat = materialList[i]; + if (mat == null) + { + continue; + } + if (mat.name.Equals(oldMaterialName, StringComparison.OrdinalIgnoreCase)) + { + var newMaterial = AssetDatabase.LoadAssetAtPath(newMaterialPath); + + if (newMaterial != null) + { + materialList[i] = newMaterial; + } + else + { + // a material we expected to exist does not + result = false; + } + } + } + + var setMethod = property.GetSetMethod(); + if (setMethod != null) + { + setMethod.Invoke(obj, new object[] { materialList }); + } + else + { + // failed to set the material from the SetMethod + result = false; + } + } + } + + return result; + } + + private Object LoadObject(ref RunItemContext ctx) + { + var item = ctx.item; + var guid = guids[item.index]; + + if (GlobalObjectId.TryParse(guid, out var gid)) + { + var obj = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(gid); + if (!obj) + { + // Open container scene + if (gid.identifierType == (int)IdentifierType.kSceneObject) + { + var containerPath = AssetDatabase.GUIDToAssetPath(gid.assetGUID); + + var mainInstanceID = AssetDatabase.LoadAssetAtPath(containerPath); + AssetDatabase.OpenAsset(mainInstanceID); + + // if we have a prefab open, then we already have the object we need to update + var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); + if (prefabStage != null) + { + obj = mainInstanceID; + } + + // Reload object if it is still null + if (obj == null) + { + obj = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(gid); + if (!obj) + { + ctx.didFail = true; + ctx.info = $"Object {gid.assetGUID} failed to load..."; + } + } + } + } + + return obj; + } + + ctx.didFail = true; + ctx.info = $"Failed to parse Global ID {item.descriptor.info}..."; + + return null; + } + } +} diff --git a/Editor/Converter/ReadonlyMaterialConverter.cs.meta b/Editor/Converter/ReadonlyMaterialConverter.cs.meta new file mode 100644 index 0000000..71c62ac --- /dev/null +++ b/Editor/Converter/ReadonlyMaterialConverter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4c1a380894944abb81ca30ff22942075 +timeCreated: 1617302308 \ No newline at end of file diff --git a/Editor/Converter/RenderPipelineConverter.cs b/Editor/Converter/RenderPipelineConverter.cs new file mode 100644 index 0000000..445fbbe --- /dev/null +++ b/Editor/Converter/RenderPipelineConverter.cs @@ -0,0 +1,78 @@ +using System; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("PPv2URPConverters")] +namespace UnityEditor.Rendering.Universal.Converters +{ + // Might need to change this name before making it public + internal abstract class RenderPipelineConverter + { + /// + /// Name of the converter. + /// + public abstract string name { get; } + + /// + /// The information when hovering over the converter. + /// + public abstract string info { get; } + + /// + /// A check if the converter is enabled or not. Can be used to do a check if prerequisites are met to have it enabled or disabled. + /// + public virtual bool isEnabled => true; + + /// + /// A priority of the converter. The lower the number (can be negative), the earlier it will be executed. Can be used to make sure that a converter runs before another converter. + /// + public virtual int priority => 0; + + /// + /// A check to see if the converter needs to create the index. + /// This will only need to be set to true if the converter is using search api, and search queries. + /// If set to true the converter framework will create the indexer and remove it after all search queries are done. + /// + public virtual bool needsIndexing => false; + + /// + /// This method getting triggered when clicking the listview item in the UI. + /// + public virtual void OnClicked(int index) + { + } + + // This is so that we can have different segment in our UI, example Unity converters, your custom converters etc.. + // This is not implemented yet + public virtual string category { get; } + + // This is in which drop down item the converter belongs to. + // Not properly implemented yet + public abstract Type container { get; } + + /// + /// This runs when initializing the converter. To gather data for the UI and also for the converter if needed. + /// + /// The context that will be used to initialize data for the converter. + public abstract void OnInitialize(InitializeConverterContext context, Action callback); + + /// + /// The method that will be run before Run method if needed. + /// + public virtual void OnPreRun() + { + } + + /// + /// The method that will be run when converting the assets. + /// + /// The context that will be used when executing converter. + public abstract void OnRun(ref RunItemContext context); + + /// + /// The method that will be run after the converters are done if needed. + /// + public virtual void OnPostRun() + { + } + } +} diff --git a/Editor/Converter/RenderPipelineConverter.cs.meta b/Editor/Converter/RenderPipelineConverter.cs.meta new file mode 100644 index 0000000..dea58d7 --- /dev/null +++ b/Editor/Converter/RenderPipelineConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1d106637fb07dd4e8b6cf58728df825 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/RenderPipelineConverterContainer.cs b/Editor/Converter/RenderPipelineConverterContainer.cs new file mode 100644 index 0000000..aa683c5 --- /dev/null +++ b/Editor/Converter/RenderPipelineConverterContainer.cs @@ -0,0 +1,20 @@ +namespace UnityEditor.Rendering.Universal.Converters +{ + /// + /// A class to contain converters. This is for a common set of converters. + /// For example: Converters that is for Built-in to URP would have it's own container. + /// + internal abstract class RenderPipelineConverterContainer + { + /// + /// The name of the Container. This will show up int the UI. + /// + public abstract string name { get; } + + /// + /// The information for this container. + /// This will be shown in the UI to tell the user some information about the converters that this container are targeting. + /// + public abstract string info { get; } + } +} diff --git a/Editor/Converter/RenderPipelineConverterContainer.cs.meta b/Editor/Converter/RenderPipelineConverterContainer.cs.meta new file mode 100644 index 0000000..a5412b4 --- /dev/null +++ b/Editor/Converter/RenderPipelineConverterContainer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d69b82b363f561049985d33b03059590 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Converter/RenderPipelineConvertersEditor.cs b/Editor/Converter/RenderPipelineConvertersEditor.cs new file mode 100644 index 0000000..e30a697 --- /dev/null +++ b/Editor/Converter/RenderPipelineConvertersEditor.cs @@ -0,0 +1,676 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEditor.Search; +using UnityEditor.UIElements; +using UnityEngine.UIElements; +using UnityEngine.Assertions; + +namespace UnityEditor.Rendering.Universal.Converters +{ + // Status for each row item to say in which state they are in. + // This will make sure they are showing the correct icon + [Serializable] + enum Status + { + Pending, + Warning, + Error, + Success + } + + // This is the serialized class that stores the state of each item in the list of items to convert + [Serializable] + class ConverterItemState + { + public bool isActive; + + // Message that will be displayed on the icon if warning or failed. + public string message; + + // Status of the converted item, Pending, Warning, Error or Success + public Status status; + + internal bool hasConverted = false; + } + + // Each converter uses the active bool + // Each converter has a list of active items/assets + // We do this so that we can use the binding system of the UI Elements + [Serializable] + class ConverterState + { + // This is the enabled state of the whole converter + public bool isEnabled; + public bool isActive; + public bool isLoading; // to name + public bool isInitialized; + public List items = new List(); + + public int pending; + public int warnings; + public int errors; + public int success; + internal int index; + + public bool isActiveAndEnabled => isEnabled && isActive; + public bool requiresInitialization => !isInitialized && isActiveAndEnabled; + } + + [Serializable] + internal struct ConverterItems + { + public List itemDescriptors; + } + + [Serializable] + [EditorWindowTitle(title = "Render Pipeline Converters")] + internal class RenderPipelineConvertersEditor : EditorWindow + { + public VisualTreeAsset converterEditorAsset; + public VisualTreeAsset converterListAsset; + public VisualTreeAsset converterItem; + + ScrollView m_ScrollView; + + List m_CoreConvertersList = new List(); + + private bool convertButtonActive = false; + + // This list needs to be as long as the amount of converters + List m_ItemsToConvert = new List(); + //List> m_ItemsToConvert = new List>(); + SerializedObject m_SerializedObject; + + List m_ContainerChoices = new List(); + List m_Containers = new List(); + int m_ContainerChoiceIndex = 0; + + // This is a list of Converter States which holds a list of which converter items/assets are active + // There is one for each Converter. + [SerializeField] List m_ConverterStates = new List(); + + TypeCache.TypeCollection m_ConverterContainers; + + // Name of the index file + string m_URPConverterIndex = "URPConverterIndex"; + + [MenuItem("Window/Rendering/Render Pipeline Converter", false, 50)] + public static void ShowWindow() + { + RenderPipelineConvertersEditor wnd = GetWindow(); + wnd.titleContent = new GUIContent("Render Pipeline Converter"); + DontSaveToLayout(wnd); + wnd.maxSize = new Vector2(650f, 4000f); + wnd.minSize = new Vector2(650f, 400f); + wnd.Show(); + } + + internal static void DontSaveToLayout(EditorWindow wnd) + { + // Making sure that the window is not saved in layouts. + Assembly assembly = typeof(EditorWindow).Assembly; + var editorWindowType = typeof(EditorWindow); + var hostViewType = assembly.GetType("UnityEditor.HostView"); + var containerWindowType = assembly.GetType("UnityEditor.ContainerWindow"); + var parentViewField = editorWindowType.GetField("m_Parent", BindingFlags.Instance | BindingFlags.NonPublic); + var parentViewValue = parentViewField.GetValue(wnd); + // window should not be saved to layout + var containerWindowProperty = + hostViewType.GetProperty("window", BindingFlags.Instance | BindingFlags.Public); + var parentContainerWindowValue = containerWindowProperty.GetValue(parentViewValue); + var dontSaveToLayoutField = + containerWindowType.GetField("m_DontSaveToLayout", BindingFlags.Instance | BindingFlags.NonPublic); + dontSaveToLayoutField.SetValue(parentContainerWindowValue, true); + } + + void OnEnable() + { + InitIfNeeded(); + } + + void InitIfNeeded() + { + if (m_CoreConvertersList.Any()) + return; + m_CoreConvertersList = new List(); + + // This is the drop down choices. + m_ConverterContainers = TypeCache.GetTypesDerivedFrom(); + foreach (var continerType in m_ConverterContainers) + { + var container = (RenderPipelineConverterContainer)Activator.CreateInstance(continerType); + m_Containers.Add(container); + m_ContainerChoices.Add(container.name); + } + + if (m_ConverterContainers.Any()) + { + GetConverters(); + } + else + { + ClearConverterStates(); + } + } + + void ClearConverterStates() + { + m_CoreConvertersList.Clear(); + m_ConverterStates.Clear(); + m_ItemsToConvert.Clear(); + } + + void GetConverters() + { + ClearConverterStates(); + var converterList = TypeCache.GetTypesDerivedFrom(); + + for (int i = 0; i < converterList.Count; ++i) + { + // Iterate over the converters that are used by the current container + RenderPipelineConverter conv = (RenderPipelineConverter)Activator.CreateInstance(converterList[i]); + if (conv.container == m_ConverterContainers[m_ContainerChoiceIndex]) + { + m_CoreConvertersList.Add(conv); + } + } + + // this need to be sorted by Priority property + m_CoreConvertersList = m_CoreConvertersList + .OrderBy(o => o.priority).ToList(); + + for (int i = 0; i < m_CoreConvertersList.Count; i++) + { + // Create a new ConvertState which holds the active state of the converter + var converterState = new ConverterState + { + isEnabled = m_CoreConvertersList[i].isEnabled, + isActive = false, + isInitialized = false, + items = new List(), + index = i, + }; + m_ConverterStates.Add(converterState); + + // This just creates empty entries in the m_ItemsToConvert. + // This list need to have the same amount of entries as the converters + List converterItemInfos = new List(); + //m_ItemsToConvert.Add(converterItemInfos); + m_ItemsToConvert.Add(new ConverterItems { itemDescriptors = converterItemInfos }); + } + } + + public void CreateGUI() + { + InitIfNeeded(); + if (m_ConverterContainers.Any()) + { + m_SerializedObject = new SerializedObject(this); + converterEditorAsset.CloneTree(rootVisualElement); + + rootVisualElement.Q("conversionsDropDown").choices = m_ContainerChoices; + rootVisualElement.Q("conversionsDropDown").index = m_ContainerChoiceIndex; + RecreateUI(); + + var button = rootVisualElement.Q