diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d5186fc1..f4d75e854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - [UUM-133861] Fixed "Look rotation viewing vector is zero" log being spammed when holding shift while using a create tool such as Create Sprite. +- [UUM-133859] Fixed an issue in URP projects where the Editor would recompile scripts when after a rectangle selection in ProBuilder. - Fixed warnings related to obsolete API calls with Unity 6.4 and onwards. ## [6.0.9] - 2026-01-30 diff --git a/Content/Resources/Materials/EdgePickerURP.mat b/Content/Resources/Materials/EdgePickerURP.mat new file mode 100644 index 000000000..a56ae3c3e --- /dev/null +++ b/Content/Resources/Materials/EdgePickerURP.mat @@ -0,0 +1,60 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-6385779826880740979 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: EdgePickerURP + m_Shader: {fileID: 4800000, guid: 5a6aaaf03bf583c4e9adee705d3255d7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _QueueControl: 0 + - _QueueOffset: 0 + m_Colors: + - _BaseColor: {r: 0, g: 0, b: 0, a: 1} + - _Tint: {r: 1, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Content/Resources/Materials/EdgePickerURP.mat.meta b/Content/Resources/Materials/EdgePickerURP.mat.meta new file mode 100644 index 000000000..b6a287698 --- /dev/null +++ b/Content/Resources/Materials/EdgePickerURP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 70d1a6407fa29bb44b936d5325490696 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Content/Resources/Materials/FacePickerURP.mat b/Content/Resources/Materials/FacePickerURP.mat new file mode 100644 index 000000000..1641e54b6 --- /dev/null +++ b/Content/Resources/Materials/FacePickerURP.mat @@ -0,0 +1,60 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: FacePickerURP + m_Shader: {fileID: 4800000, guid: 9cb691ed12f573842860b94cad8331e1, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _QueueControl: 0 + - _QueueOffset: 0 + m_Colors: + - _BaseColor: {r: 0, g: 0, b: 0, a: 1} + - _Tint: {r: 1, g: 1, b: 1, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &4155378413201584216 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Content/Resources/Materials/FacePickerURP.mat.meta b/Content/Resources/Materials/FacePickerURP.mat.meta new file mode 100644 index 000000000..a98652630 --- /dev/null +++ b/Content/Resources/Materials/FacePickerURP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0143c5b21b48c1643bc5417c60bbf848 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Content/Resources/Materials/VertexPickerURP.mat b/Content/Resources/Materials/VertexPickerURP.mat new file mode 100644 index 000000000..f5f29bfe0 --- /dev/null +++ b/Content/Resources/Materials/VertexPickerURP.mat @@ -0,0 +1,60 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8161258857830796102 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: VertexPickerURP + m_Shader: {fileID: 4800000, guid: 488491a14dff2924db58a2ddc0b9e26f, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _QueueControl: 0 + - _QueueOffset: 0 + m_Colors: + - _BaseColor: {r: 0, g: 0, b: 0, a: 1} + - _Tint: {r: 1, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Content/Resources/Materials/VertexPickerURP.mat.meta b/Content/Resources/Materials/VertexPickerURP.mat.meta new file mode 100644 index 000000000..557809505 --- /dev/null +++ b/Content/Resources/Materials/VertexPickerURP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eae7185451278b54bb78d0d5ff3f9452 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Content/Shader/EdgePickerURP.shader b/Content/Shader/EdgePickerURP.shader new file mode 100644 index 000000000..cf46efba4 --- /dev/null +++ b/Content/Shader/EdgePickerURP.shader @@ -0,0 +1,66 @@ +Shader "Hidden/ProBuilder/EdgePickerURP" +{ + Properties {} + + SubShader + { + PackageRequirements + { + "com.unity.render-pipelines.universal": "17.0" + } + + Tags + { + "ProBuilderPicker"="EdgePass" + "RenderType"="Opaque" + "RenderPipeline"="UniversalPipeline" + "Queue"="Geometry" + "IgnoreProjector"="True" + "DisableBatching"="True" + } + + Pass + { + Name "Edges" + Tags { "LightMode"="ProBuilderPickerA" } + ZTest Less + ZWrite On + Cull Off + Blend Off + + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "ProBuilderCG_URP.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float4 color : COLOR; + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float4 color : COLOR; + }; + + Varyings vert(Attributes input) + { + Varyings output; + output.positionCS = UnityObjectToClipPosWithOffset(input.positionOS.xyz); + output.color = input.color; + return output; + } + + half4 frag(Varyings input) : SV_Target + { + clip(input.color.a - 0.75); + return input.color; + } + ENDHLSL + } + } +} diff --git a/Content/Shader/EdgePickerURP.shader.meta b/Content/Shader/EdgePickerURP.shader.meta new file mode 100644 index 000000000..97dfba536 --- /dev/null +++ b/Content/Shader/EdgePickerURP.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5a6aaaf03bf583c4e9adee705d3255d7 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Content/Shader/FacePickerURP.shader b/Content/Shader/FacePickerURP.shader new file mode 100644 index 000000000..d0a37418e --- /dev/null +++ b/Content/Shader/FacePickerURP.shader @@ -0,0 +1,68 @@ +Shader "Hidden/ProBuilder/FacePickerURP" +{ + SubShader + { + PackageRequirements + { + "com.unity.render-pipelines.universal": "17.0" + } + + Tags + { + "ProBuilderPicker"="Base" + "RenderType"="Opaque" + "RenderPipeline"="UniversalPipeline" + "Queue"="Geometry" + "DisableBatching"="True" + } + + Pass + { + Name "Base" + Tags { "LightMode"="ProBuilderPickerA" } + ZTest LEqual + ZWrite On + Cull Back + Blend Off + + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "ProBuilderCG_URP.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float4 color : COLOR; + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float4 color : COLOR; + }; + + Varyings vert(Attributes input) + { + Varyings output; + + VertexPositionInputs positions = GetVertexPositionInputs(input.positionOS.xyz); + output.positionCS = positions.positionCS; + output.color = input.color; + + return output; + } + + half4 frag(Varyings input) : SV_Target + { + return input.color; + } + ENDHLSL + } + } + + // Fallback to built-in renderer version + Fallback "Hidden/ProBuilder/VertexPicker" +} diff --git a/Content/Shader/FacePickerURP.shader.meta b/Content/Shader/FacePickerURP.shader.meta new file mode 100644 index 000000000..d80f61b10 --- /dev/null +++ b/Content/Shader/FacePickerURP.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9cb691ed12f573842860b94cad8331e1 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Content/Shader/ProBuilderCG_URP.hlsl b/Content/Shader/ProBuilderCG_URP.hlsl new file mode 100644 index 000000000..80041567b --- /dev/null +++ b/Content/Shader/ProBuilderCG_URP.hlsl @@ -0,0 +1,70 @@ +// ProBuilderCG_URP.cginc - URP-compatible version of ProBuilderCG.cginc +// Must be included AFTER: #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +// so that TransformObjectToWorld, TransformWorldToView, UNITY_MATRIX_P, unity_OrthoParams are available. + +// Is the camera in orthographic mode? (1 yes, 0 no) +#define ORTHO (1 - UNITY_MATRIX_P[3][3]) + +// How far to pull vertices towards camera in orthographic mode +const float ORTHO_CAM_OFFSET = .0001; + +inline float4 ClipToScreen(float4 v) +{ + v.xy /= v.w; + v.xy = v.xy * .5 + .5; + v.xy *= _ScreenParams.xy; + return v; +} + +inline float4 ScreenToClip(float4 v) +{ + v.z -= ORTHO_CAM_OFFSET * ORTHO; + v.xy /= _ScreenParams.xy; + v.xy = (v.xy - .5) / .5; + v.xy *= v.w; + return v; +} + +inline float4 UnityObjectToClipPosWithOffset(float3 positionOS) +{ + VertexPositionInputs positions = GetVertexPositionInputs(positionOS); + + float4 ret = float4(positions.positionVS, 1); + //Offsetting the edges to avoid z-fighting problems + //Do not offset when using orthographic camera as XY are + //screen coords, this would shift the rendering + ret.xyz *= lerp(0.99, 0.95, unity_OrthoParams.w); + //Moving edges closer + //.99 is not sufficient for Orthographic Camera + ret.w *= lerp(1, 0.95, unity_OrthoParams.w); + return mul(UNITY_MATRIX_P, ret); +} + +inline float4 UnityObjectToClipPosWithOffsetMetal(float3 positionOS) +{ + VertexPositionInputs positions = GetVertexPositionInputs(positionOS); + + float4 ret = float4(positions.positionVS, 1); + ret *= lerp(.99, .95, ORTHO); + return mul(UNITY_MATRIX_P, ret); +} + +inline float4 GetPickerColor(float4 pos, float2 texcoord1) +{ + // convert vertex to screen space, add pixel-unit xy to vertex, then transform back to clip space. + float4 clip = pos; + + clip.xy /= clip.w; + clip.xy = clip.xy * .5 + .5; + clip.xy *= _ScreenParams.xy; + + clip.xy += texcoord1.xy * 3.5; + clip.z -= .0001 * (1 - UNITY_MATRIX_P[3][3]); + + clip.xy /= _ScreenParams.xy; + clip.xy = (clip.xy - .5) / .5; + clip.xy *= clip.w; + + return clip; +} + diff --git a/Content/Shader/ProBuilderCG_URP.hlsl.meta b/Content/Shader/ProBuilderCG_URP.hlsl.meta new file mode 100644 index 000000000..43d284a56 --- /dev/null +++ b/Content/Shader/ProBuilderCG_URP.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ee82fff19db555c45baac786068d84fe +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Content/Shader/VertexPickerURP.shader b/Content/Shader/VertexPickerURP.shader new file mode 100644 index 000000000..5cd352f48 --- /dev/null +++ b/Content/Shader/VertexPickerURP.shader @@ -0,0 +1,77 @@ +Shader "Hidden/ProBuilder/VertexPickerURP" +{ + Properties {} + + SubShader + { + PackageRequirements + { + "com.unity.render-pipelines.universal": "17.0" + } + + Tags + { + "ProBuilderPicker"="VertexPass" + "RenderType"="Opaque" + "RenderPipeline"="UniversalPipeline" + "Queue"="Geometry" + "IgnoreProjector"="True" + "DisableBatching"="True" + } + + Pass + { + Name "Vertices" + // Tags { "LightMode"="SRPDefaultUnlit" } + Tags { "LightMode"="ProBuilderPickerA" } + + ZTest LEqual + ZWrite On + Cull Off + Blend Off + Offset -1, -1 + + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "ProBuilderCG_URP.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float3 normalOS : NORMAL; + float4 color : COLOR; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float2 uv : TEXCOORD0; + float4 color : COLOR; + }; + + Varyings vert(Attributes input) + { + Varyings output; + output.positionCS = UnityObjectToClipPosWithOffset(input.positionOS.xyz); + output.positionCS = GetPickerColor(output.positionCS, input.uv1); + output.uv = input.uv0.xy; + output.color = input.color; + + return output; + } + + half4 frag(Varyings input) : SV_Target + { + return input.color; + } + ENDHLSL + } + } + + Fallback "Hidden/ProBuilder/VertexPicker" +} diff --git a/Content/Shader/VertexPickerURP.shader.meta b/Content/Shader/VertexPickerURP.shader.meta new file mode 100644 index 000000000..ad3833d40 --- /dev/null +++ b/Content/Shader/VertexPickerURP.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 488491a14dff2924db58a2ddc0b9e26f +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Core/BuiltinMaterials.cs b/Runtime/Core/BuiltinMaterials.cs index 2772c75fb..57f5e1933 100644 --- a/Runtime/Core/BuiltinMaterials.cs +++ b/Runtime/Core/BuiltinMaterials.cs @@ -69,14 +69,24 @@ public static class BuiltinMaterials static Material s_UnityDefaultDiffuse; static Material s_ShapePreviewMaterial; - static string k_EdgePickerMaterial = "Materials/EdgePicker"; - static string k_FacePickerMaterial = "Materials/FacePicker"; - static string k_VertexPickerMaterial = "Materials/VertexPicker"; - +#if PB_URP_MODE + static string k_EdgePickerShader = "Hidden/ProBuilder/EdgePickerURP"; + static string k_VertexPickerShader = "Hidden/ProBuilder/VertexPickerURP"; + static string k_FacePickerShader = "Shader Graphs/FacePickerURP"; + + static string k_EdgePickerMaterial = "Materials/EdgePickerURP"; + static string k_FacePickerMaterial = "Materials/FacePickerURP"; + static string k_VertexPickerMaterial = "Materials/VertexPickerURP"; +#else static string k_EdgePickerShader = "Hidden/ProBuilder/EdgePicker"; static string k_FacePickerShader = "Hidden/ProBuilder/FacePicker"; static string k_VertexPickerShader = "Hidden/ProBuilder/VertexPicker"; + static string k_EdgePickerMaterial = "Materials/EdgePicker"; + static string k_FacePickerMaterial = "Materials/FacePicker"; + static string k_VertexPickerMaterial = "Materials/VertexPicker"; +#endif + static void Init() { if (s_IsInitialized) diff --git a/Runtime/Core/SelectionPickerRenderer.cs b/Runtime/Core/SelectionPickerRenderer.cs index a0c1da16a..ab209e02f 100644 --- a/Runtime/Core/SelectionPickerRenderer.cs +++ b/Runtime/Core/SelectionPickerRenderer.cs @@ -165,9 +165,9 @@ static ISelectionPickerRenderer pickerRenderer { if (s_PickerRenderer == null) s_PickerRenderer = - ShouldUseHDRP()? - (ISelectionPickerRenderer)new SelectionPickerRendererHDRP() - : new SelectionPickerRendererStandard(); + ShouldUseHDRP() ? new SelectionPickerRendererHDRP() + : ShouldUseURP() ? new SelectionPickerRendererURP() + : new SelectionPickerRendererStandard(); return s_PickerRenderer; } } @@ -853,6 +853,15 @@ static bool ShouldUseHDRP() return true; #else return false; +#endif + } + + static bool ShouldUseURP() + { +#if PB_URP_MODE + return true; +#else + return false; #endif } } diff --git a/Runtime/Core/SelectionPickerRendererURP.cs b/Runtime/Core/SelectionPickerRendererURP.cs new file mode 100644 index 000000000..ca6e1abe3 --- /dev/null +++ b/Runtime/Core/SelectionPickerRendererURP.cs @@ -0,0 +1,135 @@ +using UnityEditor; +using UnityEngine.Rendering; + +#if PB_URP_MODE +using UnityEngine.Rendering.Universal; +using UObject = UnityEngine.Object; +using static UnityEngine.Rendering.RenderPipeline; +#endif + +namespace UnityEngine.ProBuilder +{ + internal partial class SelectionPickerRenderer + { + + internal class SelectionPickerRendererURP : ISelectionPickerRenderer + { + public static Camera temporaryCamera; + + /// + /// Render the camera with a replacement shader and return the resulting image. + /// RenderTexture is always initialized with no gamma conversion (RenderTextureReadWrite.Linear) + /// + /// + /// + /// + /// + /// + /// + public Texture2D RenderLookupTexture( + Camera camera, + Shader shader, + string tag, + int width = -1, + int height = -1) + { +#if PB_URP_MODE + bool autoSize = width < 0 || height < 0; + + int _width = autoSize ? (int)camera.pixelRect.width : width; + int _height = autoSize ? (int)camera.pixelRect.height : height; + + GameObject go = new GameObject(); + Camera renderCam = go.AddComponent(); + temporaryCamera = renderCam; + renderCam.CopyFrom(camera); + + renderCam.renderingPath = RenderingPath.Forward; + renderCam.enabled = false; + renderCam.clearFlags = CameraClearFlags.SolidColor; + renderCam.backgroundColor = Color.white; + renderCam.allowHDR = false; + renderCam.allowMSAA = false; + renderCam.forceIntoRenderTexture = true; + + renderCam.GetUniversalAdditionalCameraData(); + + RenderTextureDescriptor descriptor = new RenderTextureDescriptor() + { + width = _width, + height = _height, + colorFormat = renderTextureFormat, + autoGenerateMips = false, + depthBufferBits = 16, + dimension = UnityEngine.Rendering.TextureDimension.Tex2D, + enableRandomWrite = false, + memoryless = RenderTextureMemoryless.None, + sRGB = false, + useMipMap = false, + volumeDepth = 1, + msaaSamples = 1 + }; + + + RenderTexture rt = RenderTexture.GetTemporary(descriptor); +#if PB_DEBUG + /* Debug.Log(string.Format("antiAliasing {0}\nautoGenerateMips {1}\ncolorBuffer {2}\ndepth {3}\ndepthBuffer {4}\ndimension {5}\nenableRandomWrite {6}\nformat {7}\nheight {8}\nmemorylessMode {9}\nsRGB {10}\nuseMipMap {11}\nvolumeDepth {12}\nwidth {13}", + RenderTexture.active.antiAliasing, + RenderTexture.active.autoGenerateMips, + RenderTexture.active.colorBuffer, + RenderTexture.active.depth, + RenderTexture.active.depthBuffer, + RenderTexture.active.dimension, + RenderTexture.active.enableRandomWrite, + RenderTexture.active.format, + RenderTexture.active.height, + RenderTexture.active.memorylessMode, + RenderTexture.active.sRGB, + RenderTexture.active.useMipMap, + RenderTexture.active.volumeDepth, + RenderTexture.active.width)); + */ +#endif + var request = new StandardRequest() + { + destination = rt + }; + RenderPipelineManager.beginCameraRendering += CustomRenderPass; + + if (RenderPipeline.SupportsRenderRequest(renderCam, request) == false) + Debug.LogWarning("RenderRequest not supported."); + + RenderPipeline.SubmitRenderRequest(renderCam, request); + RenderTexture prev = RenderTexture.active; + RenderTexture.active = rt; + + Texture2D img = new Texture2D(_width, _height, textureFormat, false, false); + img.ReadPixels(new Rect(0, 0, _width, _height), 0, 0); + img.Apply(); + + RenderTexture.active = prev; + RenderTexture.ReleaseTemporary(rt); + RenderPipelineManager.beginCameraRendering -= CustomRenderPass; + temporaryCamera = null; + UObject.DestroyImmediate(go); + + return img; +#else + return null; +#endif + } + +#if PB_URP_MODE + static void CustomRenderPass(ScriptableRenderContext ctx, Camera camera) + { + if (camera != temporaryCamera) + return; + var customPass = new URPSelectionPickerPass(-1); + customPass.renderPassEvent = RenderPassEvent.AfterRendering; + + camera.GetUniversalAdditionalCameraData().scriptableRenderer.EnqueuePass(customPass); + } +#endif + } + } +} diff --git a/Runtime/Core/SelectionPickerRendererURP.cs.meta b/Runtime/Core/SelectionPickerRendererURP.cs.meta new file mode 100644 index 000000000..3981e7621 --- /dev/null +++ b/Runtime/Core/SelectionPickerRendererURP.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 10d0f8b62703b4d48a0f6af6b6773163 \ No newline at end of file diff --git a/Runtime/Core/URPSelectionPickerPass.cs b/Runtime/Core/URPSelectionPickerPass.cs new file mode 100644 index 000000000..9533a31f7 --- /dev/null +++ b/Runtime/Core/URPSelectionPickerPass.cs @@ -0,0 +1,98 @@ +#if PB_URP_MODE +using System.Collections.Generic; +using UnityEngine.Rendering; +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.Universal; + +namespace UnityEngine.ProBuilder +{ + class URPSelectionPickerPass : ScriptableRenderPass + { + // List of shader tags used to build the renderer list. + private List m_ShaderTagIdList = new List(); + + public URPSelectionPickerPass(LayerMask layerMask) + { + } + + // This class stores the data needed by the pass, passed as parameter to the delegate function that executes the pass. + private class PassData + { + public RendererListHandle rendererListHandle; + } + + // Sample utility method that showcases how to create a renderer list via the RenderGraph API. + private void InitRendererLists(ContextContainer frameData, ref PassData passData, RenderGraph renderGraph) + { + // Access the relevant frame data from the Universal Render Pipeline. + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalCameraData cameraData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + var sortFlags = cameraData.defaultOpaqueSortFlags; + RenderQueueRange renderQueueRange = RenderQueueRange.opaque; + FilteringSettings filterSettings = new FilteringSettings(renderQueueRange, -1); + + ShaderTagId[] forwardOnlyShaderTagIds = new ShaderTagId[] + { + new ShaderTagId("ProBuilderPickerA") + }; + + m_ShaderTagIdList.Clear(); + + foreach (ShaderTagId sid in forwardOnlyShaderTagIds) + m_ShaderTagIdList.Add(sid); + + DrawingSettings drawSettings = RenderingUtils.CreateDrawingSettings(m_ShaderTagIdList, + universalRenderingData, cameraData, lightData, sortFlags); + + var param = new RendererListParams(universalRenderingData.cullResults, drawSettings, filterSettings); + passData.rendererListHandle = renderGraph.CreateRendererList(param); + } + + // This static method is used to execute the pass and passed as the RenderFunc delegate to the RenderGraph render pass. + static void ExecutePass(PassData data, RasterGraphContext context) + { + context.cmd.ClearRenderTarget(RTClearFlags.Color, Color.white, 1, 0); + + context.cmd.DrawRendererList(data.rendererListHandle); + } + + // This is where the renderGraph handle can be accessed. + // Each ScriptableRenderPass can use the RenderGraph handle to add multiple render passes to the render graph. + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + string passName = "ProBuilder Selection Picker Pass"; + + // This simple pass clears the current active color texture, then renders the scene geometry associated to the m_LayerMask layer. + // Add scene geometry to your own custom layers and experiment switching the layer mask in the render feature UI. + // You can use the frame debugger to inspect the pass output. + + // add a raster render pass to the render graph, specifying the name and the data type that will be passed to the ExecutePass function + using (var builder = renderGraph.AddRasterRenderPass(passName, out var passData)) + { + // UniversalResourceData contains all the texture handles used by the renderer, including the active color and depth textures + // The active color and depth textures are the main color and depth buffers that the camera renders into. + UniversalResourceData resourceData = frameData.Get(); + + // Fill up the passData with the data needed by the pass. + InitRendererLists(frameData, ref passData, renderGraph); + + // Optional check to make sure the rendererList is valid. If it isn't, the pass will not execute (instead of the render graph possibly throwing an error). + if (!passData.rendererListHandle.IsValid()) + return; + + // We declare the RendererList we just created as an input dependency to this pass, via UseRendererList(). + builder.UseRendererList(passData.rendererListHandle); + + // Setup as a render target via UseTextureFragment and UseTextureFragmentDepth, which are the equivalent of using the old cmd.SetRenderTarget(color,depth) + builder.SetRenderAttachment(resourceData.activeColorTexture, 0); + builder.SetRenderAttachmentDepth(resourceData.activeDepthTexture, AccessFlags.Write); + + // Assign the ExecutePass function to the render pass delegate, which will be called by the render graph when executing the pass. + builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => ExecutePass(data, context)); + } + } + } +} +#endif diff --git a/Runtime/Core/URPSelectionPickerPass.cs.meta b/Runtime/Core/URPSelectionPickerPass.cs.meta new file mode 100644 index 000000000..00f64d4a6 --- /dev/null +++ b/Runtime/Core/URPSelectionPickerPass.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ab752184a0d6df845ae5fc6966304066 \ No newline at end of file diff --git a/Runtime/Core/URPSelectionPickerRenderFeature.cs b/Runtime/Core/URPSelectionPickerRenderFeature.cs new file mode 100644 index 000000000..876c59622 --- /dev/null +++ b/Runtime/Core/URPSelectionPickerRenderFeature.cs @@ -0,0 +1,25 @@ +#if PB_URP_MODE +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace UnityEngine.ProBuilder +{ + class CustomPassFeature : ScriptableRendererFeature + { + URPSelectionPickerPass customPass; + public LayerMask m_LayerMask; + + + public override void Create() + { + customPass = new URPSelectionPickerPass(m_LayerMask); + customPass.renderPassEvent = RenderPassEvent.AfterRendering; + } + + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + renderer.EnqueuePass(customPass); + } + } +} +#endif diff --git a/Runtime/Core/URPSelectionPickerRenderFeature.cs.meta b/Runtime/Core/URPSelectionPickerRenderFeature.cs.meta new file mode 100644 index 000000000..2f5866985 --- /dev/null +++ b/Runtime/Core/URPSelectionPickerRenderFeature.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ec1254965d75036429e441b88861c535 \ No newline at end of file diff --git a/Runtime/Unity.ProBuilder.asmdef b/Runtime/Unity.ProBuilder.asmdef index adfece40c..89b3aebd5 100644 --- a/Runtime/Unity.ProBuilder.asmdef +++ b/Runtime/Unity.ProBuilder.asmdef @@ -1,9 +1,12 @@ { "name": "Unity.ProBuilder", + "rootNamespace": "", "references": [ "Unity.ProBuilder.Poly2Tri", "Unity.ProBuilder.KdTree", - "Unity.RenderPipelines.HighDefinition.Runtime" + "Unity.RenderPipelines.HighDefinition.Runtime", + "Unity.RenderPipelines.Universal.Runtime", + "Unity.RenderPipelines.Core.Runtime" ], "includePlatforms": [], "excludePlatforms": [], @@ -22,6 +25,11 @@ "name": "com.unity.modules.particlesystem", "expression": "1.0.0", "define": "USING_PARTICLE_SYSTEM" + }, + { + "name": "com.unity.render-pipelines.universal", + "expression": "17.0.0", + "define": "PB_URP_MODE" } ], "noEngineReferences": false