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