From ac1f15f686283efc2d424553ed8f29ea36f4dec3 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 6 Jul 2020 22:17:58 +0300 Subject: [PATCH 01/23] Changed default render event to AfterSkybox (before transparent pass) --- .../Examples/SimplePerCamera/Outline.unity | 4 +- .../Examples/SimplePerCamera/Transparent.mat | 78 +++++++++++++++++++ .../SimplePerCamera/Transparent.mat.meta | 8 ++ .../Runtime/Scripts/OutlineRenderer.cs | 14 ++-- 4 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat create mode 100644 Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat.meta diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity index 5a17553..966be73 100644 --- a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity @@ -304,7 +304,7 @@ MonoBehaviour: m_EditorClassIdentifier: _outlineResources: {fileID: 11400000, guid: d28e70f030b1a634db9a6a6d5478ef19, type: 2} _outlineLayers: {fileID: 11400000, guid: 3a6c3b3c5f6e3ad4ab8e09fc219865bd, type: 2} - _cameraEvent: 18 + _cameraEvent: 15 --- !u!1 &748173439 GameObject: m_ObjectHideFlags: 0 @@ -432,7 +432,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 2100000, guid: fba6bd852efa3814e9fa0e4788cc192d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat b/Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat new file mode 100644 index 0000000..0bfc481 --- /dev/null +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat @@ -0,0 +1,78 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Transparent + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: _ALPHAPREMULTIPLY_ON + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 0 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 0.5176471} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat.meta b/Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat.meta new file mode 100644 index 0000000..6bf95c8 --- /dev/null +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Transparent.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fba6bd852efa3814e9fa0e4788cc192d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index 6ac7e84..409052b 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -55,7 +55,7 @@ namespace UnityFx.Outline /// /// A default outline rendering should be assosiated with. /// - public const CameraEvent RenderEvent = CameraEvent.BeforeImageEffects; + public const CameraEvent RenderEvent = CameraEvent.AfterSkybox; /// /// Initializes a new instance of the struct. @@ -233,8 +233,10 @@ public void Render(IReadOnlyList renderers, IOutlineSettings settings, } _commandBuffer.BeginSample(sampleName); - RenderObject(settings, renderers); - RenderOutline(settings); + { + RenderObject(settings, renderers); + RenderOutline(settings); + } _commandBuffer.EndSample(sampleName); } } @@ -266,8 +268,10 @@ public void Render(Renderer renderer, IOutlineSettings settings, string sampleNa } _commandBuffer.BeginSample(sampleName); - RenderObject(settings, renderer); - RenderOutline(settings); + { + RenderObject(settings, renderer); + RenderOutline(settings); + } _commandBuffer.EndSample(sampleName); } From 2d30a29503f40a1436373d017ddcb5ff0aa4b22e Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 7 Aug 2020 22:21:43 +0300 Subject: [PATCH 02/23] Added support for alpha testing (fixes #10) --- .../Examples/SimplePerCamera/Cutout.mat | 78 +++++++++ .../Examples/SimplePerCamera/Outline.unity | 148 +++++++++++++++++- .../Examples/SimplePerCamera/TestImage.png | Bin 0 -> 12824 bytes .../Runtime/Scripts/OutlineRenderFlags.cs | 9 +- .../Runtime/Scripts/OutlineRenderer.cs | 59 ++++--- .../Runtime/Shaders/OutlineColor.shader | 19 +++ 6 files changed, 279 insertions(+), 34 deletions(-) create mode 100644 Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat create mode 100644 Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat b/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat new file mode 100644 index 0000000..728bc81 --- /dev/null +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat @@ -0,0 +1,78 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Cutout + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: _ALPHATEST_ON + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2450 + stringTagMap: + RenderType: TransparentCutout + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 4de367982d1c341a58cfc851a06f21ef, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 1 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity index 966be73..38be0d3 100644 --- a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657844, g: 0.49641222, b: 0.57481694, a: 1} + m_IndirectSpecularColor: {r: 0.44657868, g: 0.4964124, b: 0.574817, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -54,7 +54,7 @@ LightmapSettings: m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 1 m_LightmapEditorSettings: - serializedVersion: 10 + serializedVersion: 12 m_Resolution: 2 m_BakeResolution: 40 m_AtlasSize: 1024 @@ -62,6 +62,7 @@ LightmapSettings: m_AOMaxDistance: 1 m_CompAOExponent: 1 m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 m_Padding: 2 m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 @@ -76,10 +77,16 @@ LightmapSettings: m_PVRDirectSampleCount: 32 m_PVRSampleCount: 500 m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 m_PVRFilterTypeDirect: 0 m_PVRFilterTypeIndirect: 0 m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 + m_PVREnvironmentMIS: 0 m_PVRCulling: 1 m_PVRFilteringGaussRadiusDirect: 1 m_PVRFilteringGaussRadiusIndirect: 5 @@ -87,7 +94,9 @@ LightmapSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} m_UseShadowmask: 1 --- !u!196 &4 @@ -137,12 +146,14 @@ Light: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 167171210} m_Enabled: 1 - serializedVersion: 8 + serializedVersion: 10 m_Type: 1 + m_Shape: 0 m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} m_Intensity: 0.5 m_Range: 10 m_SpotAngle: 30 + m_InnerSpotAngle: 21.802082 m_CookieSize: 10 m_Shadows: m_Type: 2 @@ -152,6 +163,24 @@ Light: m_Bias: 0.05 m_NormalBias: 0.4 m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 m_Cookie: {fileID: 0} m_DrawHalo: 0 m_Flare: {fileID: 0} @@ -159,12 +188,15 @@ Light: m_CullingMask: serializedVersion: 2 m_Bits: 4294967295 + m_RenderingLayerMask: 1 m_Lightmapping: 4 m_LightShadowCasterMode: 0 m_AreaSize: {x: 1, y: 1} m_BounceIntensity: 1 m_ColorTemperature: 6570 m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 m_ShadowRadius: 0 m_ShadowAngle: 0 --- !u!4 &167171212 @@ -231,6 +263,8 @@ MonoBehaviour: LayerIndex: 0 - Go: {fileID: 748173439} LayerIndex: 1 + - Go: {fileID: 1150463983} + LayerIndex: 0 --- !u!20 &692811815 Camera: m_ObjectHideFlags: 0 @@ -243,9 +277,10 @@ Camera: m_ClearFlags: 1 m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 @@ -287,6 +322,7 @@ Transform: - {fileID: 1579373806} - {fileID: 748173443} - {fileID: 1789341921} + - {fileID: 1150463984} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -338,6 +374,7 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -349,6 +386,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -396,6 +434,100 @@ Transform: m_Father: {fileID: 692811816} m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1150463983 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1150463984} + - component: {fileID: 1150463987} + - component: {fileID: 1150463986} + - component: {fileID: 1150463985} + m_Layer: 0 + m_Name: Quad + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1150463984 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1150463983} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -2.14, y: 0, z: 3.84} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 692811816} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!64 &1150463985 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1150463983} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1150463986 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1150463983} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 246a4aa17578f4fa9b38d3256c78855e, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &1150463987 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1150463983} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!1 &1579373802 GameObject: m_ObjectHideFlags: 0 @@ -429,6 +561,7 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -440,6 +573,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -556,6 +690,7 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -567,6 +702,7 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png b/Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png new file mode 100644 index 0000000000000000000000000000000000000000..b8bfe95b57f4c5f68353b798ecdf3649bc696e07 GIT binary patch literal 12824 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 literal 0 HcmV?d00001 diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderFlags.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderFlags.cs index d180f46..2f94e9b 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderFlags.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderFlags.cs @@ -22,8 +22,13 @@ public enum OutlineRenderFlags Blurred = 1, /// - /// Enabled depth testing when rendering object outlines. Only visible parts of objects are outlined. + /// Enables depth testing when rendering object outlines. Only visible parts of objects are outlined. /// - EnableDepthTesting = 2 + EnableDepthTesting = 2, + + /// + /// Enabled alpha testing when rendering outlines. + /// + EnableAlphaTesting = 4 } } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index 409052b..944ee1f 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -36,8 +36,10 @@ namespace UnityFx.Outline { #region data - private const int _hPassId = 0; - private const int _vPassId = 1; + private const int _defaultRenderPassId = 0; + private const int _alphaTestRenderPassId = 1; + private const int _outlineHPassId = 0; + private const int _outlineVPassId = 1; private const RenderTextureFormat _rtFormat = RenderTextureFormat.R8; private static readonly int _maskRtId = Shader.PropertyToID("_MaskTex"); @@ -323,45 +325,50 @@ private void RenderObjectClear(OutlineRenderFlags flags) _commandBuffer.ClearRenderTarget(false, true, Color.clear); } - private void RenderObject(IOutlineSettings settings, IReadOnlyList renderers) + private void DrawRenderer(Renderer renderer, IOutlineSettings settings) { - RenderObjectClear(settings.OutlineRenderMode); - - for (var i = 0; i < renderers.Count; ++i) + if (renderer && renderer.enabled && renderer.isVisible && renderer.gameObject.activeInHierarchy) { - var r = renderers[i]; + var alphaTest = (settings.OutlineRenderMode & OutlineRenderFlags.EnableAlphaTesting) != 0; - if (r && r.enabled && r.isVisible && r.gameObject.activeInHierarchy) - { - // NOTE: Accessing Renderer.sharedMaterials triggers GC.Alloc. That's why we use a temporary - // list of materials, cached with the outline resources. - r.GetSharedMaterials(_resources.TmpMaterials); + // NOTE: Accessing Renderer.sharedMaterials triggers GC.Alloc. That's why we use a temporary + // list of materials, cached with the outline resources. + renderer.GetSharedMaterials(_resources.TmpMaterials); - for (var j = 0; j < _resources.TmpMaterials.Count; ++j) + if (alphaTest) + { + for (var i = 0; i < _resources.TmpMaterials.Count; ++i) { - _commandBuffer.DrawRenderer(r, _resources.RenderMaterial, j); + _commandBuffer.SetGlobalTexture(_resources.MainTexId, _resources.TmpMaterials[i].mainTexture); + _commandBuffer.DrawRenderer(renderer, _resources.RenderMaterial, i, _alphaTestRenderPassId); + } + } + else + { + for (var i = 0; i < _resources.TmpMaterials.Count; ++i) + { + _commandBuffer.DrawRenderer(renderer, _resources.RenderMaterial, i, _defaultRenderPassId); } } } } - private void RenderObject(IOutlineSettings settings, Renderer renderer) + private void RenderObject(IOutlineSettings settings, IReadOnlyList renderers) { RenderObjectClear(settings.OutlineRenderMode); - if (renderer && renderer.enabled && renderer.isVisible && renderer.gameObject.activeInHierarchy) + for (var i = 0; i < renderers.Count; ++i) { - // NOTE: Accessing Renderer.sharedMaterials triggers GC.Alloc. That's why we use a temporary - // list of materials, cached with the outline resources. - renderer.GetSharedMaterials(_resources.TmpMaterials); - - for (var i = 0; i < _resources.TmpMaterials.Count; ++i) - { - _commandBuffer.DrawRenderer(renderer, _resources.RenderMaterial, i); - } + DrawRenderer(renderers[i], settings); } } + private void RenderObject(IOutlineSettings settings, Renderer renderer) + { + RenderObjectClear(settings.OutlineRenderMode); + DrawRenderer(renderer, settings); + } + private void RenderOutline(IOutlineSettings settings) { var mat = _resources.OutlineMaterial; @@ -371,11 +378,11 @@ private void RenderOutline(IOutlineSettings settings) // HPass _commandBuffer.SetRenderTarget(_hPassRtId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); - Blit(_commandBuffer, _maskRtId, _resources, _hPassId, mat, props); + Blit(_commandBuffer, _maskRtId, _resources, _outlineHPassId, mat, props); // VPassBlend _commandBuffer.SetRenderTarget(_rt, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); - Blit(_commandBuffer, _hPassRtId, _resources, _vPassId, mat, props); + Blit(_commandBuffer, _hPassRtId, _resources, _outlineVPassId, mat, props); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader index bca1a57..84117d0 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader @@ -9,11 +9,20 @@ Shader "Hidden/UnityFx/OutlineColor" #include "UnityCG.cginc" + UNITY_DECLARE_TEX2D(_MainTex); + half4 frag() : SV_Target { return 1; } + half4 frag_clip(appdata_img i) : SV_Target + { + half4 c = UNITY_SAMPLE_TEX2D(_MainTex, i.texcoord); + clip(c.a - 1); + return 1; + } + ENDHLSL SubShader @@ -32,5 +41,15 @@ Shader "Hidden/UnityFx/OutlineColor" ENDHLSL } + + Pass + { + HLSLPROGRAM + + #pragma vertex vert_img + #pragma fragment frag_clip + + ENDHLSL + } } } From 4fdac1fafffdaf293ee7fe5071f05a381cb92e9b Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 7 Aug 2020 22:22:39 +0300 Subject: [PATCH 03/23] CHANGELOG update --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1728fd..13f1dab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/). +## [0.8.1] - unreleased + +Alpha test support and misc improvements. + +### Added +- Added support for alpha-test when rendering outlines. + +### Changed +- Changed default render event to AfterSkybox. + ## [0.8.0] - 2020.05.30 [URP](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@8.1/manual/index.html) support, core refactoring and bugfixes. From 85d5ff359062cbad5505a6d887571f1f0a66aafd Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 7 Aug 2020 22:25:05 +0300 Subject: [PATCH 04/23] README update --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9fff0c8..0c4244c 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,8 @@ Supported outline parameters are: - Width (in pixels); - Type (solid or blurred); - Intensity (for blurred outlines); -- Depth testing. +- Depth testing; +- Alpha testing. Supported platforms: - Windows/Mac standalone; @@ -66,7 +67,7 @@ Npm core package is available at [npmjs.com](https://www.npmjs.com/package/com.u } ], "dependencies": { - "com.unityfx.outline": "0.8.0", + "com.unityfx.outline": "0.8.1", "com.unityfx.outline.urp": "0.1.0", } } @@ -147,6 +148,12 @@ outlineSettings.OutlineWidth = 2; outlineSettings.OutlineRenderMode = OutlineRenderFlags.Blurred | OutlineRenderFlags.EnableDepthTesting; ``` +### Alpha testing +By default alpha testing is disabled when rendering outlines. This behaviour can be overriden by setting `EnableAlphaTesting` flag of `Rander Flags` (either via scripting API or with editor). +```csharp +outlineSettings.OutlineRenderMode = OutlineRenderFlags.EnableAlphaTesting; +``` + ### Ignore layers When adding a `GameObject` to outline collection it is often desirable to ignore child renderers in specific layers (for instance, `TransparentFX`). This can be achieved by settings the `IgnoreLayers` mask in outline settings (or through corresponding API). ```csharp From 23c65fb43531f79f41413e7df18ed75ddb5e017d Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Tue, 11 Aug 2020 20:59:20 +0300 Subject: [PATCH 05/23] Added render event support to OutlineBehaviour (#11) --- .../Editor/Scripts/OutlineBehaviourEditor.cs | 9 +++++ .../Runtime/Scripts/OutlineBehaviour.cs | 33 +++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs index 17b32c6..c4d3431 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs @@ -6,6 +6,7 @@ using UnityEditorInternal; using UnityEditor.SceneManagement; using UnityEngine; +using UnityEngine.Rendering; namespace UnityFx.Outline { @@ -37,6 +38,14 @@ public override void OnInspectorGUI() _effect.IgnoreLayerMask = mask; } + var e = (CameraEvent)EditorGUILayout.EnumPopup("Render Event", _effect.RenderEvent); + + if (e != _effect.RenderEvent) + { + Undo.RecordObject(_effect, "Set Render Event"); + _effect.RenderEvent = e; + } + var obj = (OutlineSettings)EditorGUILayout.ObjectField("Outline Settings", _effect.OutlineSettings, typeof(OutlineSettings), true); if (_effect.OutlineSettings != obj) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index 96daed1..b144fd5 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -27,6 +27,8 @@ public sealed class OutlineBehaviour : MonoBehaviour, IOutlineSettings private OutlineSettingsInstance _outlineSettings; [SerializeField, HideInInspector] private int _layerMask; + [SerializeField, HideInInspector] + private CameraEvent _cameraEvent = OutlineRenderer.RenderEvent; [SerializeField, Tooltip("If set, list of object renderers is updated on each frame. Enable if the object has child renderers which are enabled/disabled frequently.")] private bool _updateRenderers; @@ -107,6 +109,33 @@ public int IgnoreLayerMask } } + /// + /// Gets or sets used to render the outlines. + /// + public CameraEvent RenderEvent + { + get + { + return _cameraEvent; + } + set + { + if (_cameraEvent != value) + { + foreach (var kvp in _cameraMap) + { + if (kvp.Key) + { + kvp.Key.RemoveCommandBuffer(_cameraEvent, kvp.Value); + kvp.Key.AddCommandBuffer(value, kvp.Value); + } + } + + _cameraEvent = value; + } + } + } + /// /// Gets outline renderers. By default all child components are used for outlining. /// @@ -157,7 +186,7 @@ private void OnDisable() { if (kvp.Key) { - kvp.Key.RemoveCommandBuffer(OutlineRenderer.RenderEvent, kvp.Value); + kvp.Key.RemoveCommandBuffer(_cameraEvent, kvp.Value); } kvp.Value.Dispose(); @@ -317,7 +346,7 @@ private void OnCameraPreRender(Camera camera) { var cmdBuf = new CommandBuffer(); cmdBuf.name = string.Format("{0} - {1}", GetType().Name, name); - camera.AddCommandBuffer(OutlineRenderer.RenderEvent, cmdBuf); + camera.AddCommandBuffer(_cameraEvent, cmdBuf); _cameraMap.Add(camera, cmdBuf); } From 50f6ab0e198fe61bb6c1b079fbc55c8d02b63e5e Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Tue, 11 Aug 2020 22:43:50 +0300 Subject: [PATCH 06/23] Added possibility to render outlines to specified camera only for OutlineBehaviour --- .../SimplePerCamera/TestOutlineLayers.asset | 2 +- .../Editor/Scripts/OutlineBehaviourEditor.cs | 8 ++++ .../Runtime/Scripts/OutlineBehaviour.cs | 45 ++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/TestOutlineLayers.asset b/Outline.Core/Assets/Examples/SimplePerCamera/TestOutlineLayers.asset index 0c2023b..3707e2e 100644 --- a/Outline.Core/Assets/Examples/SimplePerCamera/TestOutlineLayers.asset +++ b/Outline.Core/Assets/Examples/SimplePerCamera/TestOutlineLayers.asset @@ -35,7 +35,7 @@ MonoBehaviour: _outlineColor: {r: 1, g: 0, b: 1, a: 1} _outlineWidth: 4 _outlineIntensity: 2 - _outlineMode: 0 + _outlineMode: 4 _name: The best layer _enabled: 1 _layerMask: 2 diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs index c4d3431..08ee27c 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs @@ -46,6 +46,14 @@ public override void OnInspectorGUI() _effect.RenderEvent = e; } + var c = (Camera)EditorGUILayout.ObjectField("Target Camera", _effect.Camera, typeof(Camera), true); + + if (c != _effect.Camera) + { + Undo.RecordObject(_effect, "Set Target Camera"); + _effect.Camera = c; + } + var obj = (OutlineSettings)EditorGUILayout.ObjectField("Outline Settings", _effect.OutlineSettings, typeof(OutlineSettings), true); if (_effect.OutlineSettings != obj) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index b144fd5..f5067d6 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -29,6 +29,8 @@ public sealed class OutlineBehaviour : MonoBehaviour, IOutlineSettings private int _layerMask; [SerializeField, HideInInspector] private CameraEvent _cameraEvent = OutlineRenderer.RenderEvent; + [SerializeField, HideInInspector] + private Camera _targetCamera; [SerializeField, Tooltip("If set, list of object renderers is updated on each frame. Enable if the object has child renderers which are enabled/disabled frequently.")] private bool _updateRenderers; @@ -149,9 +151,50 @@ public ICollection OutlineRenderers } } + /// + /// Gets or sets camera to render outlines to. If not set, outlines are rendered to all active cameras. + /// + /// + public Camera Camera + { + get + { + return _targetCamera; + } + set + { + if (_targetCamera != value) + { + if (value) + { + _camerasToRemove.Clear(); + + foreach (var kvp in _cameraMap) + { + if (kvp.Key && kvp.Key != value) + { + kvp.Key.RemoveCommandBuffer(_cameraEvent, kvp.Value); + kvp.Value.Dispose(); + + _camerasToRemove.Add(kvp.Key); + } + } + + foreach (var camera in _camerasToRemove) + { + _cameraMap.Remove(camera); + } + } + + _targetCamera = value; + } + } + } + /// /// Gets all cameras outline data is rendered to. /// + /// public ICollection Cameras => _cameraMap.Keys; /// @@ -335,7 +378,7 @@ public bool Equals(IOutlineSettings other) private void OnCameraPreRender(Camera camera) { - if (camera) + if (camera && (!_targetCamera || _targetCamera == camera)) { if (_outlineSettings.RequiresCameraDepth) { From 1d724ba2aed5c019fbd0b9f9f0e2574a02e23bbd Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 14 Aug 2020 00:26:14 +0300 Subject: [PATCH 07/23] Added custom drawer for OutlineSettingsInstance --- .../Editor/Scripts/OutlineBehaviourEditor.cs | 31 +------- .../Editor/Scripts/OutlineEditorUtility.cs | 50 ------------ .../Editor/Scripts/OutlineSettingsEditor.cs | 77 +++++++++++++++++-- .../Scripts/OutlineSettingsInstanceDrawer.cs | 48 ++++++++++++ .../Scripts/Properties/AssemblyInfo.cs | 1 + 5 files changed, 123 insertions(+), 84 deletions(-) create mode 100644 Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs index 08ee27c..9733658 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs @@ -14,6 +14,7 @@ namespace UnityFx.Outline public class OutlineBehaviourEditor : Editor { private OutlineBehaviour _effect; + private SerializedProperty _settingsProp; private bool _debugOpened; private bool _renderersOpened; private bool _camerasOpened; @@ -21,6 +22,7 @@ public class OutlineBehaviourEditor : Editor private void OnEnable() { _effect = (OutlineBehaviour)target; + _settingsProp = serializedObject.FindProperty("_outlineSettings"); } public override void OnInspectorGUI() @@ -54,33 +56,8 @@ public override void OnInspectorGUI() _effect.Camera = c; } - var obj = (OutlineSettings)EditorGUILayout.ObjectField("Outline Settings", _effect.OutlineSettings, typeof(OutlineSettings), true); - - if (_effect.OutlineSettings != obj) - { - Undo.RecordObject(_effect, "Set Settings"); - _effect.OutlineSettings = obj; - } - - if (obj) - { - EditorGUI.BeginDisabledGroup(true); - EditorGUI.indentLevel += 1; - - OutlineEditorUtility.Render(_effect, _effect); - - EditorGUILayout.HelpBox(string.Format("Outline settings are overriden with values from {0}.", obj.name), MessageType.Info, true); - EditorGUI.indentLevel -= 1; - EditorGUI.EndDisabledGroup(); - } - else - { - EditorGUI.indentLevel += 1; - - OutlineEditorUtility.Render(_effect, _effect); - - EditorGUI.indentLevel -= 1; - } + EditorGUILayout.PropertyField(_settingsProp); + serializedObject.ApplyModifiedProperties(); if (EditorGUI.EndChangeCheck()) { diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs index 2b8bf4c..004f2ec 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs @@ -11,56 +11,6 @@ namespace UnityFx.Outline { public static class OutlineEditorUtility { - public static void RenderDivider(Color color, int thickness = 1, int padding = 5) - { - var r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness)); - - r.height = thickness; - r.y += padding / 2; - r.x -= 2; - - EditorGUI.DrawRect(r, color); - } - - public static void Render(IOutlineSettings settings, UnityEngine.Object undoContext) - { - var color = EditorGUILayout.ColorField("Color", settings.OutlineColor); - - if (settings.OutlineColor != color) - { - Undo.RecordObject(undoContext, "Color"); - settings.OutlineColor = color; - } - - var width = EditorGUILayout.IntSlider("Width", settings.OutlineWidth, OutlineResources.MinWidth, OutlineResources.MaxWidth); - - if (settings.OutlineWidth != width) - { - Undo.RecordObject(undoContext, "Width"); - settings.OutlineWidth = width; - } - - var prevRenderMode = settings.OutlineRenderMode; - var renderMode = (OutlineRenderFlags)EditorGUILayout.EnumFlagsField("Render Flags", prevRenderMode); - - if (renderMode != prevRenderMode) - { - Undo.RecordObject(undoContext, "Render Flags"); - settings.OutlineRenderMode = renderMode; - } - - if ((renderMode & OutlineRenderFlags.Blurred) != 0) - { - var i = EditorGUILayout.Slider("Blur Intensity", settings.OutlineIntensity, OutlineResources.MinIntensity, OutlineResources.MaxIntensity); - - if (!Mathf.Approximately(settings.OutlineIntensity, i)) - { - Undo.RecordObject(undoContext, "Blur Intensity"); - settings.OutlineIntensity = i; - } - } - } - public static void RenderPreview(OutlineLayer layer, int layerIndex, bool showObjects) { if (layer != null) diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs index efa43c4..8fd5ea9 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs @@ -12,22 +12,85 @@ namespace UnityFx.Outline [CustomEditor(typeof(OutlineSettings))] public class OutlineSettingsEditor : Editor { - private OutlineSettings _settings; + private const string _colorPropName = "_outlineColor"; + private const string _widthPropName = "_outlineWidth"; + private const string _intensityPropName = "_outlineIntensity"; + private const string _renderModePropName = "_outlineMode"; + + private static readonly GUIContent _colorContent = new GUIContent("Color", "Outline color."); + private static readonly GUIContent _widthContent = new GUIContent("Width", "Outline width in pixels."); + private static readonly GUIContent _renderModeContent = new GUIContent("Render Flags", "Outline render flags. Multiple values can be selected at the same time."); + private static readonly GUIContent _intensityContent = new GUIContent("Blur Intensity", "Outline intensity value. It is only usable for blurred outlines."); public override void OnInspectorGUI() { - EditorGUI.BeginChangeCheck(); - OutlineEditorUtility.Render(_settings, _settings); + base.OnInspectorGUI(); + + var colorProp = serializedObject.FindProperty(_colorPropName); + var widthProp = serializedObject.FindProperty(_widthPropName); + var intensityProp = serializedObject.FindProperty(_intensityPropName); + var renderModeProp = serializedObject.FindProperty(_renderModePropName); + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + + EditorGUILayout.PropertyField(colorProp, _colorContent); + EditorGUILayout.PropertyField(widthProp, _widthContent); + EditorGUILayout.PropertyField(renderModeProp, _renderModeContent); + + if ((renderMode & OutlineRenderFlags.Blurred) != 0) + { + EditorGUILayout.PropertyField(intensityProp, _intensityContent); + } + + serializedObject.ApplyModifiedProperties(); + } + + internal static float GetSettingsHeight(SerializedProperty property) + { + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + var renderModeProp = property.FindPropertyRelative(_renderModePropName); + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; - if (EditorGUI.EndChangeCheck()) + if ((renderMode & OutlineRenderFlags.Blurred) != 0) { - EditorUtility.SetDirty(_settings); + return lineCy * 5; } + + return lineCy * 4; } - private void OnEnable() + internal static void DrawSettings(Rect rc, SerializedProperty property) { - _settings = (OutlineSettings)target; + var colorProp = property.FindPropertyRelative(_colorPropName); + var widthProp = property.FindPropertyRelative(_widthPropName); + var intensityProp = property.FindPropertyRelative(_intensityPropName); + var renderModeProp = property.FindPropertyRelative(_renderModePropName); + + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + } + + internal static void DrawSettings(Rect rc, SerializedObject obj) + { + var colorProp = obj.FindProperty(_colorPropName); + var widthProp = obj.FindProperty(_widthPropName); + var intensityProp = obj.FindProperty(_intensityPropName); + var renderModeProp = obj.FindProperty(_renderModePropName); + + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + } + + private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty renderModeProp) + { + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 1 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), colorProp, _colorContent); + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 2 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), widthProp, _widthContent); + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 3 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), renderModeProp, _renderModeContent); + + if ((renderMode & OutlineRenderFlags.Blurred) != 0) + { + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 4 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), intensityProp, _intensityContent); + } } } } diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs new file mode 100644 index 0000000..db32c39 --- /dev/null +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs @@ -0,0 +1,48 @@ +// Copyright (C) 2019-2020 Alexander Bogarsukov. All rights reserved. +// See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityFx.Outline +{ + [CustomPropertyDrawer(typeof(OutlineSettingsInstance))] + public class OutlineSettingsInstanceDrawer : PropertyDrawer + { + private static GUIContent _colorContent = new GUIContent("Color", ""); + private static GUIContent _widthContent = new GUIContent("Width", ""); + private static GUIContent _renderModeContent = new GUIContent("Render Flags", ""); + private static GUIContent _intensityContent = new GUIContent("Blur Intensity", ""); + + public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label) + { + var settingsProp = property.FindPropertyRelative("_outlineSettings"); + + EditorGUI.BeginProperty(rc, label, property); + EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), settingsProp); + EditorGUI.indentLevel += 1; + + if (settingsProp.objectReferenceValue) + { + EditorGUI.BeginDisabledGroup(true); + OutlineSettingsEditor.DrawSettings(rc, new SerializedObject(settingsProp.objectReferenceValue)); + EditorGUI.EndDisabledGroup(); + } + else + { + OutlineSettingsEditor.DrawSettings(rc, property); + } + + EditorGUI.indentLevel -= 1; + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return OutlineSettingsEditor.GetSettingsHeight(property); + } + } +} diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/Properties/AssemblyInfo.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/Properties/AssemblyInfo.cs index d7b9f2c..78ea24b 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/Properties/AssemblyInfo.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/Properties/AssemblyInfo.cs @@ -27,3 +27,4 @@ // Make internals visible to the editor assembly. [assembly: InternalsVisibleTo("UnityFx.Outline.Editor")] +[assembly: InternalsVisibleTo("UnityFx.Outline.URP")] From 1ce8b7cb66d8a8e4c9a569d68ecd151b76e5f3df Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Sun, 16 Aug 2020 00:19:24 +0300 Subject: [PATCH 08/23] .editorconfig update --- .editorconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.editorconfig b/.editorconfig index 9933dd0..00be4e1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,8 @@ root = true indent_style = tab trim_trailing_whitespace = true insert_final_newline = true +charset = utf-8-bom +end_of_line = crlf # (Please don't specify an indent_size here; that has too many unintended consequences.) # Code files From b277d10cf3ace7202db286276d966d827eb9528f Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Sun, 16 Aug 2020 00:19:52 +0300 Subject: [PATCH 09/23] Added OutlineSettingsWithLayerMask --- .../Editor/Scripts/OutlineSettingsEditor.cs | 77 +++++++++++++++---- .../Scripts/OutlineSettingsInstanceDrawer.cs | 25 +----- .../OutlineSettingsWithLayerMaskDrawer.cs | 27 +++++++ .../Runtime/Scripts/OutlineResources.cs | 5 ++ .../Scripts/OutlineSettingsWithLayerMask.cs | 33 ++++++++ 5 files changed, 130 insertions(+), 37 deletions(-) create mode 100644 Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs create mode 100644 Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs index 8fd5ea9..4b7eba8 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs @@ -12,11 +12,14 @@ namespace UnityFx.Outline [CustomEditor(typeof(OutlineSettings))] public class OutlineSettingsEditor : Editor { + private const string _layerMaskPropName = "_outlineLayerMask"; + private const string _settingsPropName = "_outlineSettings"; private const string _colorPropName = "_outlineColor"; private const string _widthPropName = "_outlineWidth"; private const string _intensityPropName = "_outlineIntensity"; private const string _renderModePropName = "_outlineMode"; + private static readonly GUIContent _layerMaskContent = new GUIContent("Outline Layer Mask", OutlineResources.OutlineLayerMaskTooltip); private static readonly GUIContent _colorContent = new GUIContent("Color", "Outline color."); private static readonly GUIContent _widthContent = new GUIContent("Width", "Outline width in pixels."); private static readonly GUIContent _renderModeContent = new GUIContent("Render Flags", "Outline render flags. Multiple values can be selected at the same time."); @@ -44,7 +47,7 @@ public override void OnInspectorGUI() serializedObject.ApplyModifiedProperties(); } - internal static float GetSettingsHeight(SerializedProperty property) + internal static float GetSettingsInstanceHeight(SerializedProperty property) { var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; var renderModeProp = property.FindPropertyRelative(_renderModePropName); @@ -58,26 +61,72 @@ internal static float GetSettingsHeight(SerializedProperty property) return lineCy * 4; } - internal static void DrawSettings(Rect rc, SerializedProperty property) + internal static float GetSettingsWithMaskHeight(SerializedProperty property) { - var colorProp = property.FindPropertyRelative(_colorPropName); - var widthProp = property.FindPropertyRelative(_widthPropName); - var intensityProp = property.FindPropertyRelative(_intensityPropName); - var renderModeProp = property.FindPropertyRelative(_renderModePropName); + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName); + + if (layerMaskProp.intValue != 0) + { + var renderModeProp = property.FindPropertyRelative(_renderModePropName); + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + + if ((renderMode & OutlineRenderFlags.Blurred) != 0) + { + return lineCy * 6; + } + + return lineCy * 5; + } - DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + return lineCy; } - internal static void DrawSettings(Rect rc, SerializedObject obj) - { - var colorProp = obj.FindProperty(_colorPropName); - var widthProp = obj.FindProperty(_widthPropName); - var intensityProp = obj.FindProperty(_intensityPropName); - var renderModeProp = obj.FindProperty(_renderModePropName); + internal static void DrawSettingsInstance(Rect rc, SerializedProperty property) + { + var settingsProp = property.FindPropertyRelative(_settingsPropName); + + EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), settingsProp); + EditorGUI.indentLevel += 1; + + if (settingsProp.objectReferenceValue) + { + var obj = new SerializedObject(settingsProp.objectReferenceValue); + var colorProp = obj.FindProperty(_colorPropName); + var widthProp = obj.FindProperty(_widthPropName); + var intensityProp = obj.FindProperty(_intensityPropName); + var renderModeProp = obj.FindProperty(_renderModePropName); + + EditorGUI.BeginDisabledGroup(true); + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + EditorGUI.EndDisabledGroup(); + } + else + { + var colorProp = property.FindPropertyRelative(_colorPropName); + var widthProp = property.FindPropertyRelative(_widthPropName); + var intensityProp = property.FindPropertyRelative(_intensityPropName); + var renderModeProp = property.FindPropertyRelative(_renderModePropName); + + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + } - DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + EditorGUI.indentLevel -= 1; } + internal static void DrawSettingsWithMask(Rect rc, SerializedProperty property) + { + var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName); + + EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), layerMaskProp, _layerMaskContent); + + if (layerMaskProp.intValue != 0) + { + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + DrawSettingsInstance(new Rect(rc.x, rc.y + lineCy, rc.width, rc.height - lineCy), property); + } + } + private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty renderModeProp) { var renderMode = (OutlineRenderFlags)renderModeProp.intValue; diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs index db32c39..6799a59 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs @@ -12,37 +12,16 @@ namespace UnityFx.Outline [CustomPropertyDrawer(typeof(OutlineSettingsInstance))] public class OutlineSettingsInstanceDrawer : PropertyDrawer { - private static GUIContent _colorContent = new GUIContent("Color", ""); - private static GUIContent _widthContent = new GUIContent("Width", ""); - private static GUIContent _renderModeContent = new GUIContent("Render Flags", ""); - private static GUIContent _intensityContent = new GUIContent("Blur Intensity", ""); - public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label) { - var settingsProp = property.FindPropertyRelative("_outlineSettings"); - EditorGUI.BeginProperty(rc, label, property); - EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), settingsProp); - EditorGUI.indentLevel += 1; - - if (settingsProp.objectReferenceValue) - { - EditorGUI.BeginDisabledGroup(true); - OutlineSettingsEditor.DrawSettings(rc, new SerializedObject(settingsProp.objectReferenceValue)); - EditorGUI.EndDisabledGroup(); - } - else - { - OutlineSettingsEditor.DrawSettings(rc, property); - } - - EditorGUI.indentLevel -= 1; + OutlineSettingsEditor.DrawSettingsInstance(rc, property); EditorGUI.EndProperty(); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { - return OutlineSettingsEditor.GetSettingsHeight(property); + return OutlineSettingsEditor.GetSettingsInstanceHeight(property); } } } diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs new file mode 100644 index 0000000..31cea7e --- /dev/null +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs @@ -0,0 +1,27 @@ +// Copyright (C) 2019-2020 Alexander Bogarsukov. All rights reserved. +// See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityFx.Outline +{ + [CustomPropertyDrawer(typeof(OutlineSettingsWithLayerMask))] + public class OutlineSettingsWithLayerMaskDrawer : PropertyDrawer + { + public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(rc, label, property); + OutlineSettingsEditor.DrawSettingsWithMask(rc, property); + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return OutlineSettingsEditor.GetSettingsWithMaskHeight(property); + } + } +} diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs index 3431e1f..7b58645 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs @@ -105,6 +105,11 @@ public sealed class OutlineResources : ScriptableObject /// public const string OutlineLayerCollectionTooltip = "Collection of outline layers to use. This can be used to share outline settings between multiple cameras."; + /// + /// Tooltip text for outline field. + /// + public const string OutlineLayerMaskTooltip = "Layer mask for outined objects."; + /// /// Hashed name of _MainTex shader parameter. /// diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs new file mode 100644 index 0000000..1336ffc --- /dev/null +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs @@ -0,0 +1,33 @@ +// Copyright (C) 2019-2020 Alexander Bogarsukov. All rights reserved. +// See the LICENSE.md file in the project root for more information. + +using System; +using UnityEngine; + +namespace UnityFx.Outline +{ + [Serializable] + internal class OutlineSettingsWithLayerMask : OutlineSettingsInstance + { + #region data + +#pragma warning disable 0649 + + // NOTE: There are custom editors for public components, so no need to show these in default inspector. + [SerializeField, HideInInspector] + private LayerMask _outlineLayerMask; + +#pragma warning restore 0649 + + #endregion + + #region interface + + public int OutlineLayerMask => _outlineLayerMask; + + #endregion + + #region implementation + #endregion + } +} From 4a72ac88d58498bc6ff2ea988efb864471d9415f Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 24 Aug 2020 00:12:17 +0300 Subject: [PATCH 10/23] Add missing files --- .../Examples/SimplePerCamera/Cutout.mat | 2 +- .../Examples/SimplePerCamera/Cutout.mat.meta | 8 + .../Examples/SimplePerCamera/Outline.unity | 74 +----- .../SimplePerCamera/TestImage.png.meta | 88 +++++++ .../Editor/Scripts/OutlineSettingsEditor.cs | 220 +++++++++--------- .../Scripts/OutlineSettingsInstanceDrawer.cs | 34 +-- .../OutlineSettingsInstanceDrawer.cs.meta | 11 + ...OutlineSettingsWithLayerMaskDrawer.cs.meta | 11 + .../OutlineSettingsWithLayerMask.cs.meta | 11 + .../ProjectSettings/ProjectVersion.txt | 2 +- 10 files changed, 268 insertions(+), 193 deletions(-) create mode 100644 Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat.meta create mode 100644 Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png.meta create mode 100644 Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs.meta create mode 100644 Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs.meta create mode 100644 Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs.meta diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat b/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat index 728bc81..483d94b 100644 --- a/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat @@ -41,7 +41,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MainTex: - m_Texture: {fileID: 2800000, guid: 4de367982d1c341a58cfc851a06f21ef, type: 3} + m_Texture: {fileID: 2800000, guid: 0ff6a32c354a4bd40a270e2d1e39335f, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} - _MetallicGlossMap: diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat.meta b/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat.meta new file mode 100644 index 0000000..bb419d5 --- /dev/null +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Cutout.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d11ad24ddc889ee4c9067711d2b431a4 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity index 38be0d3..d6b4733 100644 --- a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657868, g: 0.4964124, b: 0.574817, a: 1} + m_IndirectSpecularColor: {r: 0.44657844, g: 0.49641222, b: 0.57481694, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -54,7 +54,7 @@ LightmapSettings: m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 1 m_LightmapEditorSettings: - serializedVersion: 12 + serializedVersion: 10 m_Resolution: 2 m_BakeResolution: 40 m_AtlasSize: 1024 @@ -62,7 +62,6 @@ LightmapSettings: m_AOMaxDistance: 1 m_CompAOExponent: 1 m_CompAOExponentDirect: 0 - m_ExtractAmbientOcclusion: 0 m_Padding: 2 m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 @@ -77,16 +76,10 @@ LightmapSettings: m_PVRDirectSampleCount: 32 m_PVRSampleCount: 500 m_PVRBounces: 2 - m_PVREnvironmentSampleCount: 500 - m_PVREnvironmentReferencePointCount: 2048 - m_PVRFilteringMode: 2 - m_PVRDenoiserTypeDirect: 0 - m_PVRDenoiserTypeIndirect: 0 - m_PVRDenoiserTypeAO: 0 m_PVRFilterTypeDirect: 0 m_PVRFilterTypeIndirect: 0 m_PVRFilterTypeAO: 0 - m_PVREnvironmentMIS: 0 + m_PVRFilteringMode: 2 m_PVRCulling: 1 m_PVRFilteringGaussRadiusDirect: 1 m_PVRFilteringGaussRadiusIndirect: 5 @@ -94,9 +87,7 @@ LightmapSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ExportTrainingData: 0 - m_TrainingDataDestination: TrainingData - m_LightProbeSampleCountMultiplier: 4 + m_ShowResolutionOverlay: 1 m_LightingDataAsset: {fileID: 0} m_UseShadowmask: 1 --- !u!196 &4 @@ -146,14 +137,12 @@ Light: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 167171210} m_Enabled: 1 - serializedVersion: 10 + serializedVersion: 8 m_Type: 1 - m_Shape: 0 m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} m_Intensity: 0.5 m_Range: 10 m_SpotAngle: 30 - m_InnerSpotAngle: 21.802082 m_CookieSize: 10 m_Shadows: m_Type: 2 @@ -163,24 +152,6 @@ Light: m_Bias: 0.05 m_NormalBias: 0.4 m_NearPlane: 0.2 - m_CullingMatrixOverride: - e00: 1 - e01: 0 - e02: 0 - e03: 0 - e10: 0 - e11: 1 - e12: 0 - e13: 0 - e20: 0 - e21: 0 - e22: 1 - e23: 0 - e30: 0 - e31: 0 - e32: 0 - e33: 1 - m_UseCullingMatrixOverride: 0 m_Cookie: {fileID: 0} m_DrawHalo: 0 m_Flare: {fileID: 0} @@ -188,15 +159,12 @@ Light: m_CullingMask: serializedVersion: 2 m_Bits: 4294967295 - m_RenderingLayerMask: 1 m_Lightmapping: 4 m_LightShadowCasterMode: 0 m_AreaSize: {x: 1, y: 1} m_BounceIntensity: 1 m_ColorTemperature: 6570 m_UseColorTemperature: 0 - m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} - m_UseBoundingSphereOverride: 0 m_ShadowRadius: 0 m_ShadowAngle: 0 --- !u!4 &167171212 @@ -264,7 +232,7 @@ MonoBehaviour: - Go: {fileID: 748173439} LayerIndex: 1 - Go: {fileID: 1150463983} - LayerIndex: 0 + LayerIndex: 2 --- !u!20 &692811815 Camera: m_ObjectHideFlags: 0 @@ -277,10 +245,9 @@ Camera: m_ClearFlags: 1 m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} m_projectionMatrixMode: 1 - m_GateFitMode: 2 - m_FOVAxisMode: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} + m_GateFitMode: 2 m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 @@ -374,7 +341,6 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -386,7 +352,6 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 - m_ReceiveGI: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -445,7 +410,6 @@ GameObject: - component: {fileID: 1150463984} - component: {fileID: 1150463987} - component: {fileID: 1150463986} - - component: {fileID: 1150463985} m_Layer: 0 m_Name: Quad m_TagString: Untagged @@ -467,20 +431,6 @@ Transform: m_Father: {fileID: 692811816} m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!64 &1150463985 -MeshCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1150463983} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 4 - m_Convex: 0 - m_CookingOptions: 30 - m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!23 &1150463986 MeshRenderer: m_ObjectHideFlags: 0 @@ -495,11 +445,10 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 246a4aa17578f4fa9b38d3256c78855e, type: 2} + - {fileID: 2100000, guid: d11ad24ddc889ee4c9067711d2b431a4, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -507,7 +456,6 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 - m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -561,7 +509,6 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -573,7 +520,6 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 - m_ReceiveGI: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 @@ -675,6 +621,8 @@ MonoBehaviour: _outlineIntensity: 2 _outlineMode: 1 _layerMask: 0 + _cameraEvent: 15 + _targetCamera: {fileID: 0} _updateRenderers: 0 --- !u!23 &1789341923 MeshRenderer: @@ -690,7 +638,6 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -702,7 +649,6 @@ MeshRenderer: m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 - m_ReceiveGI: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png.meta b/Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png.meta new file mode 100644 index 0000000..4f4ccee --- /dev/null +++ b/Outline.Core/Assets/Examples/SimplePerCamera/TestImage.png.meta @@ -0,0 +1,88 @@ +fileFormatVersion: 2 +guid: 0ff6a32c354a4bd40a270e2d1e39335f +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs index 4b7eba8..7f4706e 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs @@ -1,71 +1,71 @@ -// Copyright (C) 2019-2020 Alexander Bogarsukov. All rights reserved. -// See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; - -namespace UnityFx.Outline -{ - [CustomEditor(typeof(OutlineSettings))] - public class OutlineSettingsEditor : Editor - { - private const string _layerMaskPropName = "_outlineLayerMask"; - private const string _settingsPropName = "_outlineSettings"; - private const string _colorPropName = "_outlineColor"; - private const string _widthPropName = "_outlineWidth"; - private const string _intensityPropName = "_outlineIntensity"; - private const string _renderModePropName = "_outlineMode"; - - private static readonly GUIContent _layerMaskContent = new GUIContent("Outline Layer Mask", OutlineResources.OutlineLayerMaskTooltip); - private static readonly GUIContent _colorContent = new GUIContent("Color", "Outline color."); - private static readonly GUIContent _widthContent = new GUIContent("Width", "Outline width in pixels."); - private static readonly GUIContent _renderModeContent = new GUIContent("Render Flags", "Outline render flags. Multiple values can be selected at the same time."); - private static readonly GUIContent _intensityContent = new GUIContent("Blur Intensity", "Outline intensity value. It is only usable for blurred outlines."); - - public override void OnInspectorGUI() - { - base.OnInspectorGUI(); - - var colorProp = serializedObject.FindProperty(_colorPropName); - var widthProp = serializedObject.FindProperty(_widthPropName); - var intensityProp = serializedObject.FindProperty(_intensityPropName); - var renderModeProp = serializedObject.FindProperty(_renderModePropName); - var renderMode = (OutlineRenderFlags)renderModeProp.intValue; - - EditorGUILayout.PropertyField(colorProp, _colorContent); - EditorGUILayout.PropertyField(widthProp, _widthContent); - EditorGUILayout.PropertyField(renderModeProp, _renderModeContent); - - if ((renderMode & OutlineRenderFlags.Blurred) != 0) - { - EditorGUILayout.PropertyField(intensityProp, _intensityContent); - } - - serializedObject.ApplyModifiedProperties(); - } - - internal static float GetSettingsInstanceHeight(SerializedProperty property) - { - var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - var renderModeProp = property.FindPropertyRelative(_renderModePropName); - var renderMode = (OutlineRenderFlags)renderModeProp.intValue; - - if ((renderMode & OutlineRenderFlags.Blurred) != 0) - { - return lineCy * 5; - } - - return lineCy * 4; - } - - internal static float GetSettingsWithMaskHeight(SerializedProperty property) - { - var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName); - +// Copyright (C) 2019-2020 Alexander Bogarsukov. All rights reserved. +// See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UnityFx.Outline +{ + [CustomEditor(typeof(OutlineSettings))] + public class OutlineSettingsEditor : Editor + { + private const string _layerMaskPropName = "_outlineLayerMask"; + private const string _settingsPropName = "_outlineSettings"; + private const string _colorPropName = "_outlineColor"; + private const string _widthPropName = "_outlineWidth"; + private const string _intensityPropName = "_outlineIntensity"; + private const string _renderModePropName = "_outlineMode"; + + private static readonly GUIContent _layerMaskContent = new GUIContent("Outline Layer Mask", OutlineResources.OutlineLayerMaskTooltip); + private static readonly GUIContent _colorContent = new GUIContent("Color", "Outline color."); + private static readonly GUIContent _widthContent = new GUIContent("Width", "Outline width in pixels."); + private static readonly GUIContent _renderModeContent = new GUIContent("Render Flags", "Outline render flags. Multiple values can be selected at the same time."); + private static readonly GUIContent _intensityContent = new GUIContent("Blur Intensity", "Outline intensity value. It is only usable for blurred outlines."); + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + var colorProp = serializedObject.FindProperty(_colorPropName); + var widthProp = serializedObject.FindProperty(_widthPropName); + var intensityProp = serializedObject.FindProperty(_intensityPropName); + var renderModeProp = serializedObject.FindProperty(_renderModePropName); + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + + EditorGUILayout.PropertyField(colorProp, _colorContent); + EditorGUILayout.PropertyField(widthProp, _widthContent); + EditorGUILayout.PropertyField(renderModeProp, _renderModeContent); + + if ((renderMode & OutlineRenderFlags.Blurred) != 0) + { + EditorGUILayout.PropertyField(intensityProp, _intensityContent); + } + + serializedObject.ApplyModifiedProperties(); + } + + internal static float GetSettingsInstanceHeight(SerializedProperty property) + { + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + var renderModeProp = property.FindPropertyRelative(_renderModePropName); + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + + if ((renderMode & OutlineRenderFlags.Blurred) != 0) + { + return lineCy * 5; + } + + return lineCy * 4; + } + + internal static float GetSettingsWithMaskHeight(SerializedProperty property) + { + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName); + if (layerMaskProp.intValue != 0) { var renderModeProp = property.FindPropertyRelative(_renderModePropName); @@ -77,43 +77,43 @@ internal static float GetSettingsWithMaskHeight(SerializedProperty property) } return lineCy * 5; - } - - return lineCy; - } - + } + + return lineCy; + } + internal static void DrawSettingsInstance(Rect rc, SerializedProperty property) { var settingsProp = property.FindPropertyRelative(_settingsPropName); - EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), settingsProp); - EditorGUI.indentLevel += 1; - - if (settingsProp.objectReferenceValue) - { - var obj = new SerializedObject(settingsProp.objectReferenceValue); + EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), settingsProp); + EditorGUI.indentLevel += 1; + + if (settingsProp.objectReferenceValue) + { + var obj = new SerializedObject(settingsProp.objectReferenceValue); var colorProp = obj.FindProperty(_colorPropName); var widthProp = obj.FindProperty(_widthPropName); var intensityProp = obj.FindProperty(_intensityPropName); - var renderModeProp = obj.FindProperty(_renderModePropName); - - EditorGUI.BeginDisabledGroup(true); - DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); - EditorGUI.EndDisabledGroup(); - } - else - { + var renderModeProp = obj.FindProperty(_renderModePropName); + + EditorGUI.BeginDisabledGroup(true); + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + EditorGUI.EndDisabledGroup(); + } + else + { var colorProp = property.FindPropertyRelative(_colorPropName); var widthProp = property.FindPropertyRelative(_widthPropName); var intensityProp = property.FindPropertyRelative(_intensityPropName); - var renderModeProp = property.FindPropertyRelative(_renderModePropName); - - DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); - } - + var renderModeProp = property.FindPropertyRelative(_renderModePropName); + + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + } + EditorGUI.indentLevel -= 1; - } - + } + internal static void DrawSettingsWithMask(Rect rc, SerializedProperty property) { var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName); @@ -127,19 +127,19 @@ internal static void DrawSettingsWithMask(Rect rc, SerializedProperty property) } } - private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty renderModeProp) - { - var renderMode = (OutlineRenderFlags)renderModeProp.intValue; - var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - - EditorGUI.PropertyField(new Rect(rc.x, rc.y + 1 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), colorProp, _colorContent); - EditorGUI.PropertyField(new Rect(rc.x, rc.y + 2 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), widthProp, _widthContent); - EditorGUI.PropertyField(new Rect(rc.x, rc.y + 3 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), renderModeProp, _renderModeContent); - - if ((renderMode & OutlineRenderFlags.Blurred) != 0) - { - EditorGUI.PropertyField(new Rect(rc.x, rc.y + 4 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), intensityProp, _intensityContent); - } - } - } -} + private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty renderModeProp) + { + var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 1 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), colorProp, _colorContent); + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 2 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), widthProp, _widthContent); + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 3 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), renderModeProp, _renderModeContent); + + if ((renderMode & OutlineRenderFlags.Blurred) != 0) + { + EditorGUI.PropertyField(new Rect(rc.x, rc.y + 4 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), intensityProp, _intensityContent); + } + } + } +} diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs index 6799a59..a6d6992 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs @@ -8,20 +8,20 @@ using UnityEngine; namespace UnityFx.Outline -{ - [CustomPropertyDrawer(typeof(OutlineSettingsInstance))] - public class OutlineSettingsInstanceDrawer : PropertyDrawer - { - public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label) - { - EditorGUI.BeginProperty(rc, label, property); - OutlineSettingsEditor.DrawSettingsInstance(rc, property); - EditorGUI.EndProperty(); - } - - public override float GetPropertyHeight(SerializedProperty property, GUIContent label) - { - return OutlineSettingsEditor.GetSettingsInstanceHeight(property); - } - } -} +{ + [CustomPropertyDrawer(typeof(OutlineSettingsInstance))] + public class OutlineSettingsInstanceDrawer : PropertyDrawer + { + public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(rc, label, property); + OutlineSettingsEditor.DrawSettingsInstance(rc, property); + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return OutlineSettingsEditor.GetSettingsInstanceHeight(property); + } + } +} diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs.meta b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs.meta new file mode 100644 index 0000000..99ae287 --- /dev/null +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsInstanceDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a7d070135166b04783f98841111c742 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs.meta b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs.meta new file mode 100644 index 0000000..358c115 --- /dev/null +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsWithLayerMaskDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5558cd049bcb613438115d59a4376272 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs.meta b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs.meta new file mode 100644 index 0000000..86fb5b9 --- /dev/null +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsWithLayerMask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f6645ede9c6d2346b6aee185f8261d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Outline.Core/ProjectSettings/ProjectVersion.txt b/Outline.Core/ProjectSettings/ProjectVersion.txt index 31a1862..895cee8 100644 --- a/Outline.Core/ProjectSettings/ProjectVersion.txt +++ b/Outline.Core/ProjectSettings/ProjectVersion.txt @@ -1 +1 @@ -m_EditorVersion: 2018.4.11f1 +m_EditorVersion: 2018.4.13f1 From 7fe2f69ea4052cd59cea004cf9c9f1e552e12fb1 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 24 Aug 2020 00:21:47 +0300 Subject: [PATCH 11/23] Added SRP not supported warnings for OutlineEffect and OutlineBehaviour --- .../Runtime/Scripts/OutlineBehaviour.cs | 5 +++++ .../UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs | 4 ++++ .../Runtime/Scripts/OutlineResources.cs | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index f5067d6..317def3 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -212,6 +212,11 @@ public void UpdateRenderers() private void Awake() { + if (GraphicsSettings.renderPipelineAsset) + { + Debug.LogWarningFormat(this, OutlineResources.SrpNotSupported, GetType().Name); + } + CreateRenderersIfNeeded(); CreateSettingsIfNeeded(); } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index 0150be3..5dbb4a9 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -156,6 +156,10 @@ public void ShareLayersWith(OutlineEffect other) private void Awake() { + if (GraphicsSettings.renderPipelineAsset) + { + Debug.LogWarningFormat(this, OutlineResources.SrpNotSupported, GetType().Name); + } } private void OnEnable() diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs index 7b58645..fbe9fcb 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs @@ -110,6 +110,16 @@ public sealed class OutlineResources : ScriptableObject /// public const string OutlineLayerMaskTooltip = "Layer mask for outined objects."; + /// + /// SRP not supported message. + /// + internal const string SrpNotSupported = "{0} does not support SRP."; + + /// + /// Post-processing not supported message. + /// + internal const string PpNotSupported = "{0} does not support Unity Post-processing stack v2."; + /// /// Hashed name of _MainTex shader parameter. /// From 68f4d0df7a3753c48dc9d4c0313e17508fa6d4f3 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 24 Aug 2020 12:06:05 +0300 Subject: [PATCH 12/23] Misc changes --- .../UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs | 4 ++++ .../Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs | 4 ++++ .../UnityFx.Outline/Runtime/Scripts/OutlineResources.cs | 4 ++-- .../UnityFx.Outline.PostProcessing/Runtime/Scripts/Outline.cs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index 317def3..494a354 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -217,6 +217,10 @@ private void Awake() Debug.LogWarningFormat(this, OutlineResources.SrpNotSupported, GetType().Name); } +#if UNITY_POST_PROCESSING_STACK_V2 + Debug.LogWarningFormat(this, OutlineResources.PpNotSupported, GetType().Name); +#endif + CreateRenderersIfNeeded(); CreateSettingsIfNeeded(); } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index 5dbb4a9..cb2093d 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -160,6 +160,10 @@ private void Awake() { Debug.LogWarningFormat(this, OutlineResources.SrpNotSupported, GetType().Name); } + +#if UNITY_POST_PROCESSING_STACK_V2 + Debug.LogWarningFormat(this, OutlineResources.PpNotSupported, GetType().Name); +#endif } private void OnEnable() diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs index fbe9fcb..c851c17 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs @@ -113,12 +113,12 @@ public sealed class OutlineResources : ScriptableObject /// /// SRP not supported message. /// - internal const string SrpNotSupported = "{0} does not support SRP."; + internal const string SrpNotSupported = "{0} works with built-in render pipeline only. It does not support SRP (including URP and HDRP)."; /// /// Post-processing not supported message. /// - internal const string PpNotSupported = "{0} does not support Unity Post-processing stack v2."; + internal const string PpNotSupported = "{0} does not support Unity Post-processing stack v2. It might not work as expected."; /// /// Hashed name of _MainTex shader parameter. diff --git a/Outline.PostProcessing/Packages/UnityFx.Outline.PostProcessing/Runtime/Scripts/Outline.cs b/Outline.PostProcessing/Packages/UnityFx.Outline.PostProcessing/Runtime/Scripts/Outline.cs index b43431e..2094d8b 100644 --- a/Outline.PostProcessing/Packages/UnityFx.Outline.PostProcessing/Runtime/Scripts/Outline.cs +++ b/Outline.PostProcessing/Packages/UnityFx.Outline.PostProcessing/Runtime/Scripts/Outline.cs @@ -25,7 +25,7 @@ public class OutlineResourcesParameter : ParameterOverride protected override void OnEnable() { - if (value == null) + if (value is null) { value = Settings._defaultResources; } From 1648fbb7d067c4fcdb4aebdc8398f0a4e669d2a5 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 24 Aug 2020 13:30:40 +0300 Subject: [PATCH 13/23] The _Cutoff value is requested from the material (#10) --- .../Scripts/OutlineLayerCollectionEditor.cs | 13 +++++ .../Editor/Scripts/OutlineSettingsEditor.cs | 52 +++++++++++++++---- .../Runtime/Scripts/IOutlineSettings.cs | 8 ++- .../Runtime/Scripts/OutlineBehaviour.cs | 15 ++++++ .../Runtime/Scripts/OutlineLayer.cs | 13 +++++ .../Runtime/Scripts/OutlineRenderer.cs | 12 +++++ .../Runtime/Scripts/OutlineResources.cs | 22 ++++++++ .../Runtime/Scripts/OutlineSettings.cs | 22 ++++++-- .../Scripts/OutlineSettingsInstance.cs | 19 ++++++- .../Runtime/Shaders/OutlineColor.shader | 3 +- 10 files changed, 162 insertions(+), 17 deletions(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs index faa90bf..1899a1b 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs @@ -93,6 +93,7 @@ private void OnDrawLayer(Rect rect, int index, bool isActive, bool isFocused) var width = layer.OutlineWidth; var renderMode = layer.OutlineRenderMode; var blurIntensity = layer.OutlineIntensity; + var alphaCutoff = layer.OutlineAlphaCutoff; EditorGUI.BeginChangeCheck(); @@ -135,6 +136,12 @@ private void OnDrawLayer(Rect rect, int index, bool isActive, bool isFocused) if ((renderMode & OutlineRenderFlags.Blurred) != 0) { blurIntensity = EditorGUI.Slider(new Rect(rect.x, y, rect.width, lineHeight), "Blur Intensity", blurIntensity, OutlineResources.MinIntensity, OutlineResources.MaxIntensity); + y += lineOffset; + } + + if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0) + { + alphaCutoff = EditorGUI.Slider(new Rect(rect.x, y, rect.width, lineHeight), "Alpha Cutoff", alphaCutoff, OutlineResources.MinAlphaCutoff, OutlineResources.MaxAlphaCutoff); } EditorGUI.EndDisabledGroup(); @@ -152,6 +159,7 @@ private void OnDrawLayer(Rect rect, int index, bool isActive, bool isFocused) layer.OutlineColor = color; layer.OutlineRenderMode = renderMode; layer.OutlineIntensity = blurIntensity; + layer.OutlineAlphaCutoff = alphaCutoff; } } @@ -169,6 +177,11 @@ private float OnGetElementHeight(int index) ++numberOfLines; } + if ((_layers[index].OutlineRenderMode & OutlineRenderFlags.EnableAlphaTesting) != 0) + { + ++numberOfLines; + } + return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * numberOfLines + EditorGUIUtility.standardVerticalSpacing; } diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs index 7f4706e..2ccb069 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineSettingsEditor.cs @@ -17,6 +17,7 @@ public class OutlineSettingsEditor : Editor private const string _colorPropName = "_outlineColor"; private const string _widthPropName = "_outlineWidth"; private const string _intensityPropName = "_outlineIntensity"; + private const string _cutoffPropName = "_outlineAlphaCutoff"; private const string _renderModePropName = "_outlineMode"; private static readonly GUIContent _layerMaskContent = new GUIContent("Outline Layer Mask", OutlineResources.OutlineLayerMaskTooltip); @@ -24,6 +25,7 @@ public class OutlineSettingsEditor : Editor private static readonly GUIContent _widthContent = new GUIContent("Width", "Outline width in pixels."); private static readonly GUIContent _renderModeContent = new GUIContent("Render Flags", "Outline render flags. Multiple values can be selected at the same time."); private static readonly GUIContent _intensityContent = new GUIContent("Blur Intensity", "Outline intensity value. It is only usable for blurred outlines."); + private static readonly GUIContent _cutoffContent = new GUIContent("Alpha Cutoff", "Outline alpha cutoff value. It is only usable when alpha testing is enabled and the material doesn't have _Cutoff property."); public override void OnInspectorGUI() { @@ -32,18 +34,26 @@ public override void OnInspectorGUI() var colorProp = serializedObject.FindProperty(_colorPropName); var widthProp = serializedObject.FindProperty(_widthPropName); var intensityProp = serializedObject.FindProperty(_intensityPropName); + var cutoffProp = serializedObject.FindProperty(_cutoffPropName); var renderModeProp = serializedObject.FindProperty(_renderModePropName); var renderMode = (OutlineRenderFlags)renderModeProp.intValue; EditorGUILayout.PropertyField(colorProp, _colorContent); EditorGUILayout.PropertyField(widthProp, _widthContent); - EditorGUILayout.PropertyField(renderModeProp, _renderModeContent); + + //EditorGUILayout.PropertyField(renderModeProp, _renderModeContent); + renderModeProp.intValue = (int)(OutlineRenderFlags)EditorGUILayout.EnumFlagsField(_renderModeContent, renderMode); if ((renderMode & OutlineRenderFlags.Blurred) != 0) { EditorGUILayout.PropertyField(intensityProp, _intensityContent); } + if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0) + { + EditorGUILayout.PropertyField(cutoffProp, _cutoffContent); + } + serializedObject.ApplyModifiedProperties(); } @@ -52,13 +62,19 @@ internal static float GetSettingsInstanceHeight(SerializedProperty property) var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; var renderModeProp = property.FindPropertyRelative(_renderModePropName); var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + var result = lineCy * 4; if ((renderMode & OutlineRenderFlags.Blurred) != 0) { - return lineCy * 5; + result += lineCy; + } + + if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0) + { + result += lineCy; } - return lineCy * 4; + return result; } internal static float GetSettingsWithMaskHeight(SerializedProperty property) @@ -70,13 +86,19 @@ internal static float GetSettingsWithMaskHeight(SerializedProperty property) { var renderModeProp = property.FindPropertyRelative(_renderModePropName); var renderMode = (OutlineRenderFlags)renderModeProp.intValue; + var result = lineCy * 5; if ((renderMode & OutlineRenderFlags.Blurred) != 0) { - return lineCy * 6; + result += lineCy; } - return lineCy * 5; + if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0) + { + result += lineCy; + } + + return result; } return lineCy; @@ -95,10 +117,11 @@ internal static void DrawSettingsInstance(Rect rc, SerializedProperty property) var colorProp = obj.FindProperty(_colorPropName); var widthProp = obj.FindProperty(_widthPropName); var intensityProp = obj.FindProperty(_intensityPropName); + var cutoffProp = obj.FindProperty(_cutoffPropName); var renderModeProp = obj.FindProperty(_renderModePropName); EditorGUI.BeginDisabledGroup(true); - DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, cutoffProp, renderModeProp); EditorGUI.EndDisabledGroup(); } else @@ -106,9 +129,10 @@ internal static void DrawSettingsInstance(Rect rc, SerializedProperty property) var colorProp = property.FindPropertyRelative(_colorPropName); var widthProp = property.FindPropertyRelative(_widthPropName); var intensityProp = property.FindPropertyRelative(_intensityPropName); + var cutoffProp = property.FindPropertyRelative(_cutoffPropName); var renderModeProp = property.FindPropertyRelative(_renderModePropName); - DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, renderModeProp); + DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, cutoffProp, renderModeProp); } EditorGUI.indentLevel -= 1; @@ -127,18 +151,26 @@ internal static void DrawSettingsWithMask(Rect rc, SerializedProperty property) } } - private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty renderModeProp) + private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty cutoffProp, SerializedProperty renderModeProp) { var renderMode = (OutlineRenderFlags)renderModeProp.intValue; var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + var n = 4; EditorGUI.PropertyField(new Rect(rc.x, rc.y + 1 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), colorProp, _colorContent); EditorGUI.PropertyField(new Rect(rc.x, rc.y + 2 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), widthProp, _widthContent); - EditorGUI.PropertyField(new Rect(rc.x, rc.y + 3 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), renderModeProp, _renderModeContent); + + // NOTE: EditorGUI.PropertyField doesn't allow multi-selection, have to use EnumFlagsField explixitly. + renderModeProp.intValue = (int)(OutlineRenderFlags)EditorGUI.EnumFlagsField(new Rect(rc.x, rc.y + 3 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), _renderModeContent, renderMode); if ((renderMode & OutlineRenderFlags.Blurred) != 0) { - EditorGUI.PropertyField(new Rect(rc.x, rc.y + 4 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), intensityProp, _intensityContent); + EditorGUI.PropertyField(new Rect(rc.x, rc.y + n++ * lineCy, rc.width, EditorGUIUtility.singleLineHeight), intensityProp, _intensityContent); + } + + if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0) + { + EditorGUI.PropertyField(new Rect(rc.x, rc.y + n * lineCy, rc.width, EditorGUIUtility.singleLineHeight), cutoffProp, _cutoffContent); } } } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/IOutlineSettings.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/IOutlineSettings.cs index c822837..e2f517d 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/IOutlineSettings.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/IOutlineSettings.cs @@ -27,13 +27,19 @@ public interface IOutlineSettings : IEquatable /// /// Gets or sets outline intensity value. Allowed range is [, ]. - /// This is used for blurred oulines only (i.e. is set to ). + /// This is used for blurred oulines only (i.e. has flag). /// /// /// /// float OutlineIntensity { get; set; } + /// + /// Gets or sets alpha cutoff value. Allowed range is [0, 1]. This is used only when has flag. + /// + /// + float OutlineAlphaCutoff { get; set; } + /// /// Gets or sets outline render mode. /// diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index 494a354..8a1622e 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -356,6 +356,21 @@ public float OutlineIntensity } } + /// + public float OutlineAlphaCutoff + { + get + { + CreateSettingsIfNeeded(); + return _outlineSettings.OutlineAlphaCutoff; + } + set + { + CreateSettingsIfNeeded(); + _outlineSettings.OutlineAlphaCutoff = value; + } + } + /// public OutlineRenderFlags OutlineRenderMode { diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index d3d71da..8ef3f88 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -275,6 +275,19 @@ public float OutlineIntensity } } + /// + public float OutlineAlphaCutoff + { + get + { + return _settings.OutlineAlphaCutoff; + } + set + { + _settings.OutlineAlphaCutoff = value; + } + } + /// public OutlineRenderFlags OutlineRenderMode { diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index 944ee1f..1cc356b 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -339,6 +339,18 @@ private void DrawRenderer(Renderer renderer, IOutlineSettings settings) { for (var i = 0; i < _resources.TmpMaterials.Count; ++i) { + var mat = _resources.TmpMaterials[i]; + + // Use material cutoff value if available. + if (mat.HasProperty(_resources.AlphaCutoffId)) + { + _commandBuffer.SetGlobalFloat(_resources.AlphaCutoffId, mat.GetFloat(_resources.AlphaCutoffId)); + } + else + { + _commandBuffer.SetGlobalFloat(_resources.AlphaCutoffId, settings.OutlineAlphaCutoff); + } + _commandBuffer.SetGlobalTexture(_resources.MainTexId, _resources.TmpMaterials[i].mainTexture); _commandBuffer.DrawRenderer(renderer, _resources.RenderMaterial, i, _alphaTestRenderPassId); } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs index c851c17..61da16c 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs @@ -60,6 +60,18 @@ public sealed class OutlineResources : ScriptableObject /// public const int SolidIntensity = 100; + /// + /// Minimum value of outline alpha cutoff parameter. + /// + /// + public const float MinAlphaCutoff = 0; + + /// + /// Maximum value of outline alpha cutoff parameter. + /// + /// + public const float MaxAlphaCutoff = 1; + /// /// Name of _MainTex shader parameter. /// @@ -80,6 +92,11 @@ public sealed class OutlineResources : ScriptableObject /// public const string IntensityName = "_Intensity"; + /// + /// Name of _Cutoff shader parameter. + /// + public const string AlphaCutoffName = "_Cutoff"; + /// /// Name of _GaussSamples shader parameter. /// @@ -140,6 +157,11 @@ public sealed class OutlineResources : ScriptableObject /// public readonly int IntensityId = Shader.PropertyToID(IntensityName); + /// + /// Hashed name of _Cutoff shader parameter. + /// + public readonly int AlphaCutoffId = Shader.PropertyToID(AlphaCutoffName); + /// /// Hashed name of _GaussSamples shader parameter. /// diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettings.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettings.cs index 1b6fe4b..6e4c4b1 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettings.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettings.cs @@ -17,10 +17,12 @@ public sealed class OutlineSettings : ScriptableObject, IOutlineSettings // NOTE: There is a custom editor for OutlineSettings, so no need to show these in default inspector. [SerializeField, HideInInspector] private Color _outlineColor = Color.red; - [SerializeField, HideInInspector] + [SerializeField, HideInInspector, Range(OutlineResources.MinWidth, OutlineResources.MaxWidth)] private int _outlineWidth = 4; - [SerializeField, HideInInspector] + [SerializeField, HideInInspector, Range(OutlineResources.MinIntensity, OutlineResources.MaxIntensity)] private float _outlineIntensity = 2; + [SerializeField, HideInInspector, Range(OutlineResources.MinAlphaCutoff, OutlineResources.MaxAlphaCutoff)] + private float _outlineAlphaCutoff = 0.9f; [SerializeField, HideInInspector] private OutlineRenderFlags _outlineMode; @@ -38,7 +40,8 @@ public static bool Equals(IOutlineSettings lhs, IOutlineSettings rhs) return lhs.OutlineColor == rhs.OutlineColor && lhs.OutlineWidth == rhs.OutlineWidth && lhs.OutlineRenderMode == rhs.OutlineRenderMode && - Mathf.Approximately(lhs.OutlineIntensity, rhs.OutlineIntensity); + Mathf.Approximately(lhs.OutlineIntensity, rhs.OutlineIntensity) && + Mathf.Approximately(lhs.OutlineAlphaCutoff, rhs.OutlineAlphaCutoff); } #endregion @@ -84,6 +87,19 @@ public float OutlineIntensity } } + /// + public float OutlineAlphaCutoff + { + get + { + return _outlineAlphaCutoff; + } + set + { + _outlineAlphaCutoff = Mathf.Clamp(value, 0, 1); + } + } + /// public OutlineRenderFlags OutlineRenderMode { diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs index b887cdd..656faef 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs @@ -18,10 +18,12 @@ internal class OutlineSettingsInstance : IOutlineSettings private OutlineSettings _outlineSettings; [SerializeField, HideInInspector] private Color _outlineColor = Color.red; - [SerializeField, HideInInspector] + [SerializeField, HideInInspector, Range(OutlineResources.MinWidth, OutlineResources.MaxWidth)] private int _outlineWidth = 4; - [SerializeField, HideInInspector] + [SerializeField, HideInInspector, Range(OutlineResources.MinIntensity, OutlineResources.MaxIntensity)] private float _outlineIntensity = 2; + [SerializeField, HideInInspector, Range(OutlineResources.MinAlphaCutoff, OutlineResources.MaxAlphaCutoff)] + private float _outlineAlphaCutoff = 0.9f; [SerializeField, HideInInspector] private OutlineRenderFlags _outlineMode; @@ -94,6 +96,19 @@ public float OutlineIntensity } } + /// + public float OutlineAlphaCutoff + { + get + { + return _outlineSettings is null ? _outlineAlphaCutoff : _outlineSettings.OutlineAlphaCutoff; + } + set + { + _outlineAlphaCutoff = Mathf.Clamp(value, 0, 1); + } + } + /// public OutlineRenderFlags OutlineRenderMode { diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader index 84117d0..a7dbbc3 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader @@ -10,6 +10,7 @@ Shader "Hidden/UnityFx/OutlineColor" #include "UnityCG.cginc" UNITY_DECLARE_TEX2D(_MainTex); + float _Cutoff; half4 frag() : SV_Target { @@ -19,7 +20,7 @@ Shader "Hidden/UnityFx/OutlineColor" half4 frag_clip(appdata_img i) : SV_Target { half4 c = UNITY_SAMPLE_TEX2D(_MainTex, i.texcoord); - clip(c.a - 1); + clip(c.a - _Cutoff); return 1; } From eb70b6ff61a3f949340aa371919c0d4adb27e2d3 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Tue, 25 Aug 2020 22:43:23 +0300 Subject: [PATCH 14/23] Misc VR-related shader fixes --- .../Runtime/Shaders/Outline.shader | 11 ++------ .../Runtime/Shaders/OutlineColor.shader | 25 +++++++++++++++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader index ec2be87..4d6b13c 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader @@ -5,13 +5,6 @@ // Modified version of 'Custom/Post Outline' shader taken from https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/. Shader "Hidden/UnityFx/Outline" { - Properties - { - _Width("Outline thickness (in pixels)", Range(1, 32)) = 5 - _Intensity("Outline intensity", Range(0.1, 100)) = 2 - _Color("Outline color", Color) = (1, 0, 0, 1) - } - HLSLINCLUDE #include "UnityCG.cginc" @@ -32,8 +25,8 @@ Shader "Hidden/UnityFx/Outline" v2f_img vert(appdata_img v) { v2f_img o; - UNITY_INITIALIZE_OUTPUT(v2f_img, o); UNITY_SETUP_INSTANCE_ID(v); + UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.pos = float4(v.vertex.xy, UNITY_NEAR_CLIP_VALUE, 1); @@ -61,8 +54,8 @@ Shader "Hidden/UnityFx/Outline" v2f_img vert(appdata_vid v) { v2f_img o; - UNITY_INITIALIZE_OUTPUT(v2f_img, o); UNITY_SETUP_INSTANCE_ID(v); + UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.pos = GetFullScreenTriangleVertexPosition(v.vertexID, UNITY_NEAR_CLIP_VALUE); diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader index a7dbbc3..ddf81aa 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader @@ -9,17 +9,32 @@ Shader "Hidden/UnityFx/OutlineColor" #include "UnityCG.cginc" - UNITY_DECLARE_TEX2D(_MainTex); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); float _Cutoff; + v2f_img vert(appdata_img v) + { + v2f_img o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_TRANSFER_INSTANCE_ID(v, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + return o; + } + half4 frag() : SV_Target { return 1; } - half4 frag_clip(appdata_img i) : SV_Target + half4 frag_clip(v2f_img i) : SV_Target { - half4 c = UNITY_SAMPLE_TEX2D(_MainTex, i.texcoord); + UNITY_SETUP_INSTANCE_ID(i); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + + half4 c = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); clip(c.a - _Cutoff); return 1; } @@ -37,7 +52,7 @@ Shader "Hidden/UnityFx/OutlineColor" { HLSLPROGRAM - #pragma vertex vert_img + #pragma vertex vert #pragma fragment frag ENDHLSL @@ -47,7 +62,7 @@ Shader "Hidden/UnityFx/OutlineColor" { HLSLPROGRAM - #pragma vertex vert_img + #pragma vertex vert #pragma fragment frag_clip ENDHLSL From d913e7c9aec2c99914971527b82b578235ec5977 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Wed, 26 Aug 2020 22:59:38 +0300 Subject: [PATCH 15/23] Instancing shader fixes --- .../Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader | 6 ++++++ .../UnityFx.Outline/Runtime/Shaders/OutlineColor.shader | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader index 4d6b13c..c71de66 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader @@ -26,6 +26,7 @@ Shader "Hidden/UnityFx/Outline" { v2f_img o; UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); @@ -55,6 +56,7 @@ Shader "Hidden/UnityFx/Outline" { v2f_img o; UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); @@ -82,12 +84,16 @@ Shader "Hidden/UnityFx/Outline" float4 frag_h(v2f_img i) : SV_Target { + UNITY_SETUP_INSTANCE_ID(i); + float intensity = CalcIntensity(i.uv, float2(_MainTex_TexelSize.x, 0)); return float4(intensity, intensity, intensity, 1); } float4 frag_v(v2f_img i) : SV_Target { + UNITY_SETUP_INSTANCE_ID(i); + if (UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MaskTex, i.uv).r > 0) { // TODO: Avoid discard/clip to improve performance on mobiles. diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader index ddf81aa..08a5f27 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader @@ -16,6 +16,7 @@ Shader "Hidden/UnityFx/OutlineColor" { v2f_img o; UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_OUTPUT(v2f, o); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); @@ -32,7 +33,6 @@ Shader "Hidden/UnityFx/OutlineColor" half4 frag_clip(v2f_img i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); half4 c = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); clip(c.a - _Cutoff); From fc6e7d0d764ccd28d5187a360c8e7d014d88cf40 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Wed, 26 Aug 2020 23:04:22 +0300 Subject: [PATCH 16/23] Fixed compile errors --- .../Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader | 4 ++-- .../UnityFx.Outline/Runtime/Shaders/OutlineColor.shader | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader index c71de66..2820ed7 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader @@ -26,7 +26,7 @@ Shader "Hidden/UnityFx/Outline" { v2f_img o; UNITY_SETUP_INSTANCE_ID(v); - UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_OUTPUT(v2f_img, o); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); @@ -56,7 +56,7 @@ Shader "Hidden/UnityFx/Outline" { v2f_img o; UNITY_SETUP_INSTANCE_ID(v); - UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_OUTPUT(v2f_img, o); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader index 08a5f27..598f87d 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader @@ -16,7 +16,7 @@ Shader "Hidden/UnityFx/OutlineColor" { v2f_img o; UNITY_SETUP_INSTANCE_ID(v); - UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_INITIALIZE_OUTPUT(v2f_img, o); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); From 9a91fbdc8af208dae5dc14a46c604c8c8f96e8db Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Sun, 30 Aug 2020 23:52:50 +0300 Subject: [PATCH 17/23] GPU Instancing-related changes --- .../SimplePerObject/TestOutlineSettings.asset | 1 + .../Runtime/Prefabs/OutlineResources.asset | 5 +- .../Runtime/Scripts/OutlineResources.cs | 59 +++++++++++++++++-- .../Runtime/Scripts/OutlineResources.cs.meta | 5 +- .../Runtime/Shaders/Outline.shader | 2 + .../Runtime/Shaders/OutlineColor.shader | 2 + 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/Outline.Core/Assets/Examples/SimplePerObject/TestOutlineSettings.asset b/Outline.Core/Assets/Examples/SimplePerObject/TestOutlineSettings.asset index a32e433..503a07e 100644 --- a/Outline.Core/Assets/Examples/SimplePerObject/TestOutlineSettings.asset +++ b/Outline.Core/Assets/Examples/SimplePerObject/TestOutlineSettings.asset @@ -15,4 +15,5 @@ MonoBehaviour: _outlineColor: {r: 1, g: 0, b: 0, a: 1} _outlineWidth: 5 _outlineIntensity: 1 + _outlineAlphaCutoff: 0.9 _outlineMode: 0 diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Prefabs/OutlineResources.asset b/Outline.Core/Packages/UnityFx.Outline/Runtime/Prefabs/OutlineResources.asset index 285880e..b00ab91 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Prefabs/OutlineResources.asset +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Prefabs/OutlineResources.asset @@ -12,5 +12,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: b503341e0a514e3489c4851727e68257, type: 3} m_Name: OutlineResources m_EditorClassIdentifier: - RenderShader: {fileID: 4800000, guid: ac20fbf75bafe454aba5ef3c098349df, type: 3} - OutlineShader: {fileID: 4800000, guid: 41c9acbf41c8245498ac9beab378de12, type: 3} + _renderShader: {fileID: 4800000, guid: ac20fbf75bafe454aba5ef3c098349df, type: 3} + _outlineShader: {fileID: 4800000, guid: 41c9acbf41c8245498ac9beab378de12, type: 3} + _enableInstancing: 0 diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs index 61da16c..cc39ab0 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using UnityEditor; using UnityEngine; namespace UnityFx.Outline @@ -16,6 +17,13 @@ public sealed class OutlineResources : ScriptableObject { #region data + [SerializeField] + private Shader _renderShader; + [SerializeField] + private Shader _outlineShader; + [SerializeField] + private bool _enableInstancing; + private Material _renderMaterial; private Material _outlineMaterial; private MaterialPropertyBlock _props; @@ -175,12 +183,24 @@ public sealed class OutlineResources : ScriptableObject /// /// Gets or sets a that renders objects outlined with a solid while color. /// - public Shader RenderShader; + public Shader RenderShader + { + get + { + return _renderShader; + } + } /// /// Gets or sets a that renders outline around the mask, that was generated with . /// - public Shader OutlineShader; + public Shader OutlineShader + { + get + { + return _outlineShader; + } + } /// /// Gets a -based material. @@ -194,7 +214,8 @@ public Material RenderMaterial _renderMaterial = new Material(RenderShader) { name = "Outline - RenderColor", - hideFlags = HideFlags.HideAndDontSave + hideFlags = HideFlags.HideAndDontSave, + enableInstancing = _enableInstancing }; } @@ -214,7 +235,8 @@ public Material OutlineMaterial _outlineMaterial = new Material(OutlineShader) { name = "Outline - Main", - hideFlags = HideFlags.HideAndDontSave + hideFlags = HideFlags.HideAndDontSave, + enableInstancing = _enableInstancing }; if (_useDrawMesh) @@ -307,6 +329,31 @@ public bool UseFullscreenTriangleMesh } } + /// + /// Gets or sets a value indicating whether instancing is enabled. + /// + public bool EnableInstancing + { + get + { + return _enableInstancing; + } + set + { + _enableInstancing = value; + + if (_renderMaterial) + { + _renderMaterial.enableInstancing = value; + } + + if (_outlineMaterial) + { + _outlineMaterial.enableInstancing = value; + } + } + } + /// /// Gets a value indicating whether the instance is in valid state. /// @@ -362,8 +409,8 @@ public float[] GetGaussSamples(int width) /// public void ResetToDefaults() { - RenderShader = Shader.Find("Hidden/UnityFx/OutlineColor"); - OutlineShader = Shader.Find("Hidden/UnityFx/Outline"); + _renderShader = Shader.Find("Hidden/UnityFx/OutlineColor"); + _outlineShader = Shader.Find("Hidden/UnityFx/Outline"); } /// diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs.meta b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs.meta index 0f1aca3..ce5153a 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs.meta +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineResources.cs.meta @@ -4,9 +4,8 @@ MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: - - RenderShader: {fileID: 4800000, guid: ac20fbf75bafe454aba5ef3c098349df, type: 3} - - HPassShader: {fileID: 4800000, guid: 41c9acbf41c8245498ac9beab378de12, type: 3} - - VPassBlendShader: {fileID: 4800000, guid: 1df0cb1700e142f4ca3b28297d3957da, type: 3} + - _renderShader: {fileID: 4800000, guid: ac20fbf75bafe454aba5ef3c098349df, type: 3} + - _outlineShader: {fileID: 4800000, guid: 41c9acbf41c8245498ac9beab378de12, type: 3} executionOrder: 0 icon: {instanceID: 0} userData: diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader index 2820ed7..82ba634 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader @@ -123,6 +123,7 @@ Shader "Hidden/UnityFx/Outline" HLSLPROGRAM #pragma target 3.5 + #pragma multi_compile_instancing #pragma shader_feature_local _USE_DRAWMESH #pragma vertex vert #pragma fragment frag_h @@ -139,6 +140,7 @@ Shader "Hidden/UnityFx/Outline" HLSLPROGRAM #pragma target 3.5 + #pragma multi_compile_instancing #pragma shader_feature_local _USE_DRAWMESH #pragma vertex vert #pragma fragment frag_v diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader index 598f87d..d44c92b 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/OutlineColor.shader @@ -52,6 +52,7 @@ Shader "Hidden/UnityFx/OutlineColor" { HLSLPROGRAM + #pragma multi_compile_instancing #pragma vertex vert #pragma fragment frag @@ -62,6 +63,7 @@ Shader "Hidden/UnityFx/OutlineColor" { HLSLPROGRAM + #pragma multi_compile_instancing #pragma vertex vert #pragma fragment frag_clip From 2f4133a40420d8e23523ba4cf3f2b52d028dda6f Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Wed, 2 Sep 2020 22:40:07 +0300 Subject: [PATCH 18/23] Added support for merging outline layer objects (fixes #12) --- .../Examples/SimplePerCamera/Outline.unity | 96 +++++++++++++++++++ .../Scripts/OutlineLayerCollectionEditor.cs | 4 +- .../Runtime/Scripts/OutlineLayer.cs | 40 +++++++- .../Runtime/Scripts/OutlineLayerCollection.cs | 31 +++++- .../Runtime/Scripts/OutlineRenderObject.cs | 20 ++-- .../Runtime/Scripts/OutlineRenderer.cs | 2 +- 6 files changed, 174 insertions(+), 19 deletions(-) diff --git a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity index d6b4733..2dd9f75 100644 --- a/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity +++ b/Outline.Core/Assets/Examples/SimplePerCamera/Outline.unity @@ -229,6 +229,8 @@ MonoBehaviour: _content: - Go: {fileID: 1579373802} LayerIndex: 0 + - Go: {fileID: 1244590621} + LayerIndex: 0 - Go: {fileID: 748173439} LayerIndex: 1 - Go: {fileID: 1150463983} @@ -290,6 +292,7 @@ Transform: - {fileID: 748173443} - {fileID: 1789341921} - {fileID: 1150463984} + - {fileID: 1244590625} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -476,6 +479,98 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1150463983} m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1244590621 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1244590625} + - component: {fileID: 1244590624} + - component: {fileID: 1244590623} + - component: {fileID: 1244590622} + m_Layer: 0 + m_Name: Capsule + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!136 &1244590622 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1244590621} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1244590623 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1244590621} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!33 &1244590624 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1244590621} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1244590625 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1244590621} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.63, y: 0, z: 4.6} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 692811816} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1579373802 GameObject: m_ObjectHideFlags: 0 @@ -619,6 +714,7 @@ MonoBehaviour: _outlineColor: {r: 0, g: 1, b: 0, a: 1} _outlineWidth: 15 _outlineIntensity: 2 + _outlineAlphaCutoff: 0.9 _outlineMode: 1 _layerMask: 0 _cameraEvent: 15 diff --git a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs index 1899a1b..207abc6 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs @@ -38,11 +38,13 @@ public override void OnInspectorGUI() EditorGUI.BeginChangeCheck(); var mask = EditorGUILayout.MaskField("Ignore layers", _layers.IgnoreLayerMask, InternalEditorUtility.layers); + var merge = EditorGUILayout.Toggle("Merge Layer Objects", _layers.MergeLayerObjects); if (EditorGUI.EndChangeCheck()) { - Undo.RecordObject(_layers, "Set Layers"); + Undo.RecordObject(_layers, "Change layer collection"); _layers.IgnoreLayerMask = mask; + _layers.MergeLayerObjects = merge; } EditorGUILayout.Space(); diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 8ef3f88..ea9264c 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -29,6 +29,7 @@ public sealed class OutlineLayer : ICollection, IReadOnlyCollection< private OutlineLayerCollection _parentCollection; private Dictionary _outlineObjects = new Dictionary(); + private List _mergedRenderers; #endregion @@ -183,12 +184,49 @@ public void GetRenderObjects(IList renderObjects) if (go && go.activeInHierarchy) { - renderObjects.Add(new OutlineRenderObject(go, kvp.Value.GetList(), _settings)); + renderObjects.Add(new OutlineRenderObject(kvp.Value.GetList(), _settings, go.name)); } } } } + /// + /// Gets all layer renderers. + /// + public IReadOnlyList GetRenderers() + { + if (_enabled) + { + if (_mergedRenderers != null) + { + _mergedRenderers.Clear(); + } + else + { + _mergedRenderers = new List(); + } + + foreach (var kvp in _outlineObjects) + { + var go = kvp.Key; + + if (go && go.activeInHierarchy) + { + var rl = kvp.Value.GetList(); + + for (var i = 0; i < rl.Count; i++) + { + _mergedRenderers.Add(rl[i]); + } + } + } + + return _mergedRenderers; + } + + return Array.Empty(); + } + #endregion #region internals diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs index a701654..578e80f 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs @@ -23,6 +23,8 @@ public sealed class OutlineLayerCollection : ScriptableObject, IList _layers = new List(); [SerializeField, HideInInspector] private int _layerMask; + [SerializeField, HideInInspector] + private bool _mergeLayerObjects; #endregion @@ -51,6 +53,21 @@ public int IgnoreLayerMask } } + /// + /// Gets or sets a value indicating whether layer game objects should be trated as one. + /// + public bool MergeLayerObjects + { + get + { + return _mergeLayerObjects; + } + set + { + _mergeLayerObjects = value; + } + } + /// /// Gets number of game objects in the layers. /// @@ -102,9 +119,19 @@ public OutlineLayer AddLayer() /// public void GetRenderObjects(IList renderObjects) { - foreach (var layer in _layers) + if (_mergeLayerObjects) + { + foreach (var layer in _layers) + { + renderObjects.Add(new OutlineRenderObject(layer.GetRenderers(), layer, layer.Name)); + } + } + else { - layer.GetRenderObjects(renderObjects); + foreach (var layer in _layers) + { + layer.GetRenderObjects(renderObjects); + } } } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderObject.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderObject.cs index fe7469a..6c5ab02 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderObject.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderObject.cs @@ -16,7 +16,7 @@ namespace UnityFx.Outline { #region data - private readonly GameObject _go; + private readonly string _tag; private readonly IReadOnlyList _renderers; private readonly IOutlineSettings _outlineSettings; @@ -25,9 +25,9 @@ namespace UnityFx.Outline #region interface /// - /// Gets the . + /// Gets the object tag name. /// - public GameObject Go => _go; + public string Tag => _tag; /// /// Gets renderers for the object. @@ -42,19 +42,11 @@ namespace UnityFx.Outline /// /// Initializes a new instance of the struct. /// - public OutlineRenderObject(GameObject go, IReadOnlyList renderers, IOutlineSettings outlineSettings) + public OutlineRenderObject(IReadOnlyList renderers, IOutlineSettings outlineSettings, string tag = null) { - _go = go; _renderers = renderers; _outlineSettings = outlineSettings; - } - - /// - /// Implicit convertino to . - /// - public static implicit operator GameObject(OutlineRenderObject o) - { - return o._go; + _tag = tag; } #endregion @@ -64,7 +56,7 @@ public static implicit operator GameObject(OutlineRenderObject o) /// public bool Equals(OutlineRenderObject other) { - return _go == other._go && _renderers == other._renderers && _outlineSettings == other._outlineSettings; + return string.CompareOrdinal(_tag, other._tag) == 0 && _renderers == other._renderers && _outlineSettings == other._outlineSettings; } #endregion diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index 1cc356b..75fc9c6 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -203,7 +203,7 @@ public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderTarg /// public void Render(OutlineRenderObject obj) { - Render(obj.Renderers, obj.OutlineSettings, obj.Go.name); + Render(obj.Renderers, obj.OutlineSettings, obj.Tag); } /// From b93bd63d1bdf23a4aa37644941c774e995d4c8ec Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Tue, 8 Sep 2020 22:00:08 +0300 Subject: [PATCH 19/23] Added RemoveGameObject convenience method to OutlineEffect (fixes #15) --- .../Runtime/Scripts/OutlineEffect.cs | 12 ++++++++++++ .../Runtime/Scripts/OutlineLayerCollection.cs | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index cb2093d..7de6c04 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -136,6 +136,18 @@ public void AddGameObject(GameObject go, int layerIndex) _outlineLayers[layerIndex].Add(go); } + /// + /// Removes the specified from . + /// + /// A to remove. + public void RemoveGameObject(GameObject go) + { + if (_outlineLayers) + { + _outlineLayers.Remove(go); + } + } + /// /// Shares with another instance. /// diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs index 578e80f..160bb83 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs @@ -135,6 +135,21 @@ public void GetRenderObjects(IList renderObjects) } } + /// + /// Removes the specified from layers. + /// + /// A to remove. + public void Remove(GameObject go) + { + foreach (var layer in _layers) + { + if (layer.Remove(go)) + { + break; + } + } + } + /// /// Removes all game objects registered in layers. /// From 67a087cf3902ce9e368c5d11be1f416a95fdc7c6 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 14 Sep 2020 23:51:52 +0300 Subject: [PATCH 20/23] Use DrawProcedural only when it is actually available (fixes #14) --- .../UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs | 8 +++++--- .../UnityFx.Outline/Runtime/Shaders/Outline.shader | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index 75fc9c6..32d2510 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -403,13 +403,15 @@ private static void Blit(CommandBuffer cmdBuffer, RenderTargetIdentifier src, Ou // Set source texture as _MainTex to match Blit behavior. cmdBuffer.SetGlobalTexture(resources.MainTexId, src); - if (SystemInfo.graphicsShaderLevel < 35 || resources.UseFullscreenTriangleMesh) + // NOTE: SystemInfo.graphicsShaderLevel check is not enough sometimes (esp. on mobiles), so there is SystemInfo.supportsInstancing + // check and a flag for forcing DrawMesh. + if (SystemInfo.graphicsShaderLevel >= 35 && SystemInfo.supportsInstancing && !resources.UseFullscreenTriangleMesh) { - cmdBuffer.DrawMesh(resources.FullscreenTriangleMesh, Matrix4x4.identity, mat, 0, shaderPass, props); + cmdBuffer.DrawProcedural(Matrix4x4.identity, mat, shaderPass, MeshTopology.Triangles, 3, 1, props); } else { - cmdBuffer.DrawProcedural(Matrix4x4.identity, mat, shaderPass, MeshTopology.Triangles, 3, 1, props); + cmdBuffer.DrawMesh(resources.FullscreenTriangleMesh, Matrix4x4.identity, mat, 0, shaderPass, props); } } diff --git a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader index 82ba634..3862749 100644 --- a/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader +++ b/Outline.Core/Packages/UnityFx.Outline/Runtime/Shaders/Outline.shader @@ -44,7 +44,7 @@ Shader "Hidden/UnityFx/Outline" UNITY_VERTEX_INPUT_INSTANCE_ID }; - float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z) + float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z = UNITY_NEAR_CLIP_VALUE) { // Generates a triangle in homogeneous clip space, s.t. // v0 = (-1, -1, 1), v1 = (3, -1, 1), v2 = (-1, 3, 1). @@ -60,7 +60,7 @@ Shader "Hidden/UnityFx/Outline" UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); - o.pos = GetFullScreenTriangleVertexPosition(v.vertexID, UNITY_NEAR_CLIP_VALUE); + o.pos = GetFullScreenTriangleVertexPosition(v.vertexID); o.uv = ComputeScreenPos(o.pos); return o; From bbc9ff16d4502ab788248d1e31fdcf84bae6373f Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 21 Sep 2020 23:03:24 +0300 Subject: [PATCH 21/23] Set default URP render pass event to AfterRenderingSkybox --- .../UnityFx.Outline.URP/Runtime/Scripts/OutlineFeature.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Outline.URP/Packages/UnityFx.Outline.URP/Runtime/Scripts/OutlineFeature.cs b/Outline.URP/Packages/UnityFx.Outline.URP/Runtime/Scripts/OutlineFeature.cs index ad6c82e..4e2d956 100644 --- a/Outline.URP/Packages/UnityFx.Outline.URP/Runtime/Scripts/OutlineFeature.cs +++ b/Outline.URP/Packages/UnityFx.Outline.URP/Runtime/Scripts/OutlineFeature.cs @@ -54,7 +54,7 @@ public override void Create() { _outlinePass = new OutlinePass(this) { - renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing + renderPassEvent = RenderPassEvent.AfterRenderingSkybox }; } From 814697c92517fe77531b42e1f5e3789027385772 Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 21 Sep 2020 23:19:34 +0300 Subject: [PATCH 22/23] CHANGELOG update --- CHANGELOG.md | 17 +++++++++++++---- .../Packages/UnityFx.Outline/CHANGELOG.md | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f1dab..ccf5497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/). -## [0.8.1] - unreleased +## [0.8.1] - 2020.09.21 -Alpha test support and misc improvements. +Alpha test support, bugfixes and misc improvements. ### Added -- Added support for alpha-test when rendering outlines. +- Added support for alpha-testing ([#10](https://github.com/Arvtesh/UnityFx.Outline/issues/10)). +- Added support for merging outline layer objects ([#12](https://github.com/Arvtesh/UnityFx.Outline/issues/12)). +- Added `RemoveGameObject` helper methof to `OutlineEffect` ([#15](https://github.com/Arvtesh/UnityFx.Outline/issues/15)). +- Added ability to customize render event in `OutlineBehaviour`. +- Added ability to render outlines to the specified camera only for `OutlineBehaviour`. +- Added warning for unsupported render pipelines for `OutlineBehaviour` and `OutlineEffect`. ### Changed -- Changed default render event to AfterSkybox. +- Misc inspector improvements. +- Changed default render event to `AfterSkybox`. + +### Fixed +- Fixed incorrect condition for selection of render method, which sometimes caused problems with outline rendering on mobiles ([#14](https://github.com/Arvtesh/UnityFx.Outline/issues/14)). ## [0.8.0] - 2020.05.30 diff --git a/Outline.Core/Packages/UnityFx.Outline/CHANGELOG.md b/Outline.Core/Packages/UnityFx.Outline/CHANGELOG.md index 0460817..7254ca7 100644 --- a/Outline.Core/Packages/UnityFx.Outline/CHANGELOG.md +++ b/Outline.Core/Packages/UnityFx.Outline/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/). +## [0.8.1] - 2020.09.21 + +Alpha test support, bugfixes and misc improvements. + +### Added +- Added support for alpha-testing ([#10](https://github.com/Arvtesh/UnityFx.Outline/issues/10)). +- Added support for merging outline layer objects ([#12](https://github.com/Arvtesh/UnityFx.Outline/issues/12)). +- Added `RemoveGameObject` helper methof to `OutlineEffect` ([#15](https://github.com/Arvtesh/UnityFx.Outline/issues/15)). +- Added ability to customize render event in `OutlineBehaviour`. +- Added ability to render outlines to the specified camera only for `OutlineBehaviour`. +- Added warning for unsupported render pipelines for `OutlineBehaviour` and `OutlineEffect`. + +### Changed +- Misc inspector improvements. +- Changed default render event to `AfterSkybox`. + +### Fixed +- Fixed incorrect condition for selection of render method, which sometimes caused problems with outline rendering on mobiles ([#14](https://github.com/Arvtesh/UnityFx.Outline/issues/14)). + ## [0.8.0] - 2020.05.30 Major refactoring and bugfixes. From 8adb5a847afc74afcb40962cf1cdd24e601d4adf Mon Sep 17 00:00:00 2001 From: Arvtesh <22732458+Arvtesh@users.noreply.github.com> Date: Mon, 21 Sep 2020 23:19:46 +0300 Subject: [PATCH 23/23] Package version update --- Outline.Core/Packages/UnityFx.Outline/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Outline.Core/Packages/UnityFx.Outline/package.json b/Outline.Core/Packages/UnityFx.Outline/package.json index 6dc340f..9f478fc 100644 --- a/Outline.Core/Packages/UnityFx.Outline/package.json +++ b/Outline.Core/Packages/UnityFx.Outline/package.json @@ -1,6 +1,6 @@ { "name": "com.unityfx.outline", - "version": "0.8.0", + "version": "0.8.1", "displayName": "Outline toolkit", "description": "This package contains configurable per-object and per-camera outline effect implementation for built-in render pipeline. Both solid and blurred outline modes are supported (Gauss blur), as well as depth testing. Reusable and extensible API.", "unity": "2018.4",