Skip to content

Commit a22231a

Browse files
committed
Upload Package
1 parent 1c6dc49 commit a22231a

21 files changed

Lines changed: 737 additions & 0 deletions

LICENSE.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Outline-Feature.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

RendererFeature.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
using System.Collections.Generic;
2+
using UnityEngine;
3+
using UnityEngine.Rendering;
4+
using UnityEngine.Rendering.Universal;
5+
6+
namespace Outline.Feature
7+
{
8+
public class MultiSelectionOutlineFeature : ScriptableRendererFeature
9+
{
10+
public struct SelectionOutlineData
11+
{
12+
public int colorId;
13+
public List<Renderer> renderers;
14+
}
15+
16+
[System.Serializable]
17+
public class MultiSelectionOutlineSettings
18+
{
19+
public bool IsEnabled = true;
20+
public RenderPassEvent WhenToInsert = RenderPassEvent.AfterRendering;
21+
public LayerMask Filters;
22+
public Material MaterialToBlit;
23+
}
24+
25+
// MUST be named "settings" (lowercase) to be shown in the Render Features inspector
26+
public MultiSelectionOutlineSettings settings = new MultiSelectionOutlineSettings();
27+
28+
public List<SelectionOutlineData> datas
29+
{
30+
get => m_MultiSelectionOutlineRenderPass.datas;
31+
set => m_MultiSelectionOutlineRenderPass.datas = value;
32+
}
33+
34+
public int paletteId
35+
{
36+
get => m_MultiSelectionOutlineRenderPass.paletteId;
37+
set => m_MultiSelectionOutlineRenderPass.paletteId = value;
38+
}
39+
40+
RenderTargetHandle m_RenderTextureHandle;
41+
MultiSelectionOutlineRenderPass m_MultiSelectionOutlineRenderPass;
42+
43+
static readonly int s_ColorPalette = Shader.PropertyToID("_ColorPalette");
44+
45+
public override void Create()
46+
{
47+
m_MultiSelectionOutlineRenderPass = new MultiSelectionOutlineRenderPass(
48+
"MulitiSelection Outline pass",
49+
settings.WhenToInsert,
50+
settings.Filters,
51+
settings.MaterialToBlit
52+
);
53+
}
54+
55+
// called every frame once per camera
56+
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
57+
{
58+
if (!settings.IsEnabled)
59+
{
60+
// we can do nothing this frame if we want
61+
return;
62+
}
63+
64+
m_MultiSelectionOutlineRenderPass.source = renderer.cameraColorTarget;
65+
renderer.EnqueuePass(m_MultiSelectionOutlineRenderPass);
66+
}
67+
68+
public void ChangePalette(Texture2D palette)
69+
{
70+
settings.MaterialToBlit.SetTexture(s_ColorPalette, palette);
71+
}
72+
}
73+
74+
class MultiSelectionOutlineRenderPass : ScriptableRenderPass
75+
{
76+
public enum PassId
77+
{
78+
SelectionPassMask = 0,
79+
SelectionPassOutline,
80+
SelectionPassBlur,
81+
SelectionPassFinal
82+
};
83+
84+
static readonly int s_BlurDirection = Shader.PropertyToID("_BlurDirection");
85+
static readonly int s_Id = Shader.PropertyToID("_Id");
86+
static readonly int s_PaletteId = Shader.PropertyToID("_PaletteId");
87+
88+
// used to label this pass in Unity's Frame Debug utility
89+
string profilerTag;
90+
91+
Material materialToBlit;
92+
93+
RenderTargetHandle m_maskTexture;
94+
RenderTargetHandle m_blurTexture;
95+
RenderTargetHandle m_finalTexture;
96+
97+
bool isPaletteDirty;
98+
Texture2D colorPalette;
99+
100+
public RenderTargetIdentifier source { get; set; }
101+
102+
public List<MultiSelectionOutlineFeature.SelectionOutlineData> datas { get; set; }
103+
public int paletteId { get; set; }
104+
105+
public MultiSelectionOutlineRenderPass(string profilerTag,
106+
RenderPassEvent renderPassEvent, int layerMask, Material materialToBlit)
107+
{
108+
this.profilerTag = profilerTag;
109+
this.renderPassEvent = renderPassEvent;
110+
this.materialToBlit = materialToBlit;
111+
112+
m_maskTexture.Init("_MaskTexture");
113+
m_blurTexture.Init("_BlurTexture");
114+
m_finalTexture.Init("_FinalTexture");
115+
116+
datas = new List<MultiSelectionOutlineFeature.SelectionOutlineData>();
117+
paletteId = 0;
118+
}
119+
120+
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
121+
{
122+
// create a temporary render texture that matches the camera
123+
cmd.GetTemporaryRT(m_maskTexture.id, cameraTextureDescriptor);
124+
cmd.GetTemporaryRT(m_blurTexture.id, cameraTextureDescriptor);
125+
126+
var tempRTD = cameraTextureDescriptor;
127+
tempRTD.colorFormat = RenderTextureFormat.ARGB32;
128+
cmd.GetTemporaryRT(m_finalTexture.id, tempRTD);
129+
}
130+
131+
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
132+
{
133+
if (datas.Count > 0)
134+
{
135+
// fetch a command buffer to use
136+
CommandBuffer cmd = CommandBufferPool.Get(profilerTag);
137+
cmd.Clear();
138+
139+
CoreUtils.SetRenderTarget(cmd, m_finalTexture.Identifier(), ClearFlag.All, Color.clear);
140+
141+
foreach (var data in datas)
142+
{
143+
CoreUtils.SetRenderTarget(cmd, m_maskTexture.Identifier(), ClearFlag.All, Color.clear);
144+
145+
var removed = new List<int>();
146+
for (var i = 0; i < data.renderers.Count; ++i)
147+
{
148+
var renderer = data.renderers[i];
149+
if (renderer == null)
150+
{
151+
removed.Add(i);
152+
continue;
153+
}
154+
155+
cmd.DrawRenderer(renderer, materialToBlit, 0, (int)PassId.SelectionPassMask);
156+
}
157+
158+
foreach (var index in removed)
159+
data.renderers.RemoveAt(index);
160+
161+
cmd.SetGlobalColor(s_BlurDirection, new Color(1, 0, 0, 0));
162+
cmd.Blit(m_maskTexture.id, m_blurTexture.id, materialToBlit, (int)PassId.SelectionPassBlur);
163+
CheckStereoKeyword(ref renderingData, ref cmd);
164+
165+
cmd.SetGlobalColor(s_BlurDirection, new Color(0, 1, 0, 0));
166+
cmd.Blit(m_blurTexture.id, m_maskTexture.id, materialToBlit, (int)PassId.SelectionPassBlur);
167+
CheckStereoKeyword(ref renderingData, ref cmd);
168+
169+
cmd.SetGlobalFloat(s_Id, data.colorId);
170+
cmd.SetGlobalFloat(s_PaletteId, paletteId);
171+
cmd.Blit(m_maskTexture.id, m_finalTexture.id, materialToBlit, (int)PassId.SelectionPassOutline);
172+
CheckStereoKeyword(ref renderingData, ref cmd);
173+
}
174+
175+
cmd.Blit(m_finalTexture.id, source, materialToBlit, (int)PassId.SelectionPassFinal);
176+
CheckStereoKeyword(ref renderingData, ref cmd);
177+
178+
context.ExecuteCommandBuffer(cmd);
179+
cmd.Clear();
180+
181+
CommandBufferPool.Release(cmd);
182+
}
183+
}
184+
185+
void CheckStereoKeyword(ref RenderingData renderingData, ref CommandBuffer cmd)
186+
{
187+
// Add the following code snippet after calling cmd.Blit
188+
// in 2020.2+URP, cmd.Blit has a bug to turn off stereo shader keyword. Enable keyword again manually.
189+
if (renderingData.cameraData.isStereoEnabled)
190+
{
191+
if (SystemInfo.supportsMultiview)
192+
cmd.EnableShaderKeyword("STEREO_MULTIVIEW_ON");
193+
else
194+
cmd.EnableShaderKeyword("STEREO_INSTANCING_ON");
195+
}
196+
else
197+
{
198+
cmd.DisableShaderKeyword("STEREO_MULTIVIEW_ON");
199+
cmd.DisableShaderKeyword("STEREO_INSTANCING_ON");
200+
}
201+
}
202+
203+
public override void FrameCleanup(CommandBuffer cmd)
204+
{
205+
cmd.ReleaseTemporaryRT(m_maskTexture.id);
206+
cmd.ReleaseTemporaryRT(m_blurTexture.id);
207+
cmd.ReleaseTemporaryRT(m_finalTexture.id);
208+
}
209+
}
210+
}

RendererFeature/MultiSelectionOutlineFeature.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "Render.Feature",
3+
"rootNamespace": "",
4+
"references": [
5+
"GUID:15fc0a57446b3144c949da3e2b9737a9",
6+
"GUID:df380645f10b7bc4b97d4f5eb6303d95"
7+
],
8+
"includePlatforms": [],
9+
"excludePlatforms": [],
10+
"allowUnsafeCode": false,
11+
"overrideReferences": false,
12+
"precompiledReferences": [],
13+
"autoReferenced": true,
14+
"defineConstraints": [],
15+
"versionDefines": [],
16+
"noEngineReferences": false
17+
}

RendererFeature/Render.Feature.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using UnityEngine;
5+
#if ENABLE_INPUT_SYSTEM
6+
using UnityEngine.InputSystem;
7+
#endif
8+
9+
namespace Outline.Feature
10+
{
11+
[RequireComponent(typeof(ObjectOutline))]
12+
public class HighlightObjectSelection : MonoBehaviour
13+
{
14+
private ObjectOutline objectOutline;
15+
16+
private void Awake()
17+
{
18+
objectOutline = GetComponent<ObjectOutline>();
19+
}
20+
21+
#if ENABLE_INPUT_SYSTEM
22+
public void OnSelect(InputValue value)
23+
{
24+
if (!value.isPressed)
25+
{
26+
return;
27+
}
28+
29+
if (Mouse.current != null)
30+
{
31+
Vector2 mousePos = Mouse.current.position.ReadValue();
32+
if (Physics.Raycast(Camera.main.ScreenPointToRay(mousePos), out RaycastHit hit))
33+
{
34+
List<GameObject> listOfHighlightedGameObject = new List<GameObject>();
35+
36+
//Uncomment this if you want it to work with PiXYZ
37+
/*if (hit.transform.TryGetComponent(out Pixyz.ImportSDK.Metadata pixyzMetaData))
38+
{
39+
if ((!listOfHighlightedGameObject.Contains(hit.transform.gameObject)))
40+
{
41+
listOfHighlightedGameObject.Add(hit.collider.gameObject);
42+
}
43+
}*/
44+
45+
//Uncomment this if you want it to work with Reflect
46+
/*if (hit.transform.TryGetComponent(out UnityEngine.Reflect.Metadata reflectMetaData))
47+
{
48+
if ((!listOfHighlightedGameObject.Contains(hit.transform.gameObject)))
49+
{
50+
listOfHighlightedGameObject.Add(hit.collider.gameObject);
51+
}
52+
}*/
53+
54+
//Uncomment this if you want it to work without the plugin above
55+
/*if(!listOfHighlightedGameObject.Contains(hit.transform.gameObject))
56+
{
57+
listOfHighlightedGameObject.Add(hit.transform.gameObject);
58+
}*/
59+
60+
61+
if(listOfHighlightedGameObject.Count == 0) return;
62+
objectOutline?.ChangePalette();
63+
objectOutline?.Outline(listOfHighlightedGameObject);
64+
}
65+
else
66+
{
67+
objectOutline?.ClearSelection();
68+
}
69+
}
70+
}
71+
#endif
72+
}
73+
}
74+

0 commit comments

Comments
 (0)