GreenScreenManager.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. //======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
  2. using UnityEngine;
  3. using System.IO;
  4. #if ZED_HDRP || ZED_URP
  5. using UnityEngine.Rendering;
  6. #endif
  7. /// <summary>
  8. /// When attached to an object that also has a ZEDRenderingPlane, removes all real-world pixels
  9. /// of a specified color. Useful for third-person mixed reality setups.
  10. /// Also requires the Frame object of the ZEDRenderingPlane component to have its MeshRenderer material set to Mat_ZED_GreenScreen.
  11. /// The simplest way to use the plugin's GreenScreen feature is to use the ZED_GreenScreen prefab in the GreenScreen sample folder.
  12. /// For detailed information on using the ZED for greenscreen effects, see https://docs.stereolabs.com/mixed-reality/unity/green-screen-vr/.
  13. /// </summary>
  14. //[RequireComponent(typeof(ZEDManager))]
  15. public class GreenScreenManager : MonoBehaviour
  16. {
  17. /// <summary>
  18. /// The plane used for rendering. Equal to the canvas value of ZEDRenderingPlane.
  19. /// </summary>
  20. private GameObject screen = null;
  21. /// <summary>
  22. /// The Camera that this script is attached to. Only needed in SRP for a callback, since OnPreRender won't work.
  23. /// </summary>
  24. private Camera cam;
  25. /// <summary>
  26. /// The screen manager script. Automatically assigned in OnEnable().
  27. /// </summary>
  28. public ZEDManager cameraManager = null;
  29. /// <summary>
  30. /// The screen manager script. Automatically assigned in OnEnable().
  31. /// </summary>
  32. public ZEDRenderingPlane screenManager = null;
  33. /// <summary>
  34. /// Set to true when there is data available from a configuration file that needs to be loaded.
  35. /// It will then be loaded the next call to Update().
  36. /// </summary>
  37. private bool toUpdateConfig = false;
  38. /// <summary>
  39. /// Holds chroma key settings together in a single serializable object.
  40. /// </summary>
  41. [System.Serializable]
  42. public struct ChromaKey
  43. {
  44. public Color color;
  45. public float smoothness;
  46. public float range;
  47. }
  48. /// <summary>
  49. /// Holds chroma key data together in a single serializable object.
  50. /// </summary>
  51. [System.Serializable]
  52. public struct ChromaKeyData
  53. {
  54. public ChromaKey chromaKeys;
  55. public int erosion;
  56. public int numberBlurIterations;
  57. public float blurPower;
  58. public float whiteClip;
  59. public float blackClip;
  60. public float spill;
  61. }
  62. /// <summary>
  63. /// Holds greenscreen and garbage matte configuration data together in a single serializable object.
  64. /// </summary>
  65. [System.Serializable]
  66. public struct GreenScreenData
  67. {
  68. public ChromaKeyData chromaKeyData;
  69. public GarbageMatte.GarbageMatteData garbageMatteData;
  70. }
  71. /// <summary>
  72. /// Array of available chroma key settings
  73. /// </summary>
  74. public ChromaKey keys;
  75. /// <summary>
  76. /// Array of available key colors
  77. /// </summary>
  78. [SerializeField]
  79. public Color keyColors = new Color(0.0f, 1.0f, 0.0f, 1);
  80. /// <summary>
  81. /// Causes pixels on the edge of the range to the color to fade out, instead of all pixels being 100% or 0% visible.
  82. /// </summary>
  83. [SerializeField]
  84. public float smoothness;
  85. /// <summary>
  86. /// Governs how similar a pixel must be to the chosen color to get removed.
  87. /// </summary>
  88. [SerializeField]
  89. public float range;
  90. /// <summary>
  91. /// subtracts the color value from the foreground image, making it appear "less green" for instance.
  92. /// Useful because bright lighting can cause the color of a greenscreen to spill onto your actual subject.
  93. /// </summary>
  94. [SerializeField]
  95. public float spill = 0.2f;
  96. /// <summary>
  97. /// Default green color for the chroma key.
  98. /// </summary>
  99. private Color defaultColor = new Color(0.0f, 1.0f, 0.0f, 1);
  100. /// <summary>
  101. /// Default Smoothness value.
  102. /// </summary>
  103. private const float defaultSmoothness = 0.08f;
  104. /// <summary>
  105. /// Default Range value.
  106. /// </summary>
  107. private const float defaultRange = 0.42f;
  108. /// <summary>
  109. /// Default Spill value.
  110. /// </summary>
  111. private const float defaultSpill = 0.1f;
  112. /// <summary>
  113. /// Default Erosion value.
  114. /// </summary>
  115. private const int defaultErosion = 0;
  116. /// <summary>
  117. /// Default White Clip value.
  118. /// </summary>
  119. private const float defaultWhiteClip = 1.0f;
  120. /// <summary>
  121. /// Default Black Clip value.
  122. /// </summary>
  123. private const float defaultBlackClip = 0.0f;
  124. /// <summary>
  125. /// Default sigma.
  126. /// </summary>
  127. private const float defaultSigma = 0.1f;
  128. /// <summary>
  129. /// Final rendering material, eg. the material on the ZEDRenderingPlane's canvas object.
  130. /// </summary>
  131. public Material finalMat;
  132. /// <summary>
  133. /// Green screen effect material.
  134. /// </summary>
  135. private Material greenScreenMat;
  136. /// <summary>
  137. /// Material used to apply preprocessing effects in OnPreRender.
  138. /// </summary>
  139. private Material preprocessMat;
  140. /// <summary>
  141. /// Alpha texture for blending.
  142. /// </summary>
  143. private RenderTexture finalTexture;
  144. /// <summary>
  145. /// Public accessor for the alpha texture used for blending.
  146. /// </summary>
  147. public RenderTexture FinalTexture
  148. {
  149. get { return finalTexture; }
  150. }
  151. /// <summary>
  152. /// Available canals (views) for displaying the chroma key effect.
  153. /// </summary>
  154. public enum CANAL
  155. {
  156. FOREGROUND,
  157. BACKGROUND,
  158. ALPHA,
  159. KEY,
  160. FINAL
  161. };
  162. /// <summary>
  163. /// The current view. Change to see different steps of the rendering stage, which can be helpful for tweaking other settings.
  164. /// </summary>
  165. [HideInInspector]
  166. [SerializeField]
  167. public CANAL canal = CANAL.FINAL;
  168. /// <summary>
  169. /// Carves off pixels from the edges between the foreground and background.
  170. /// </summary>
  171. [HideInInspector]
  172. [SerializeField]
  173. public int erosion = 0;
  174. /// <summary>
  175. /// Causes pixels with alpha values above its setting to be set to 100% alpha, useful for reducing noise resulting from the smoothness setting.
  176. /// </summary>
  177. [SerializeField]
  178. public float whiteClip = 1.0f;
  179. /// <summary>
  180. /// Causes pixels with alpha values below its setting to be set to 0% alpha, useful for reducing noise resulting from the smoothness setting.
  181. /// </summary>
  182. [SerializeField]
  183. public float blackClip = 0.0f;
  184. /// <summary>
  185. /// The path to the .config file, where configurations would be loaded or saved when you press the relevant button.
  186. /// </summary>
  187. [SerializeField]
  188. public string pathFileConfig = "Assets/Config_greenscreen.json";
  189. /// <summary>
  190. /// Material used to apply blur effect in OnPreRender().
  191. /// </summary>
  192. private Material blurMaterial;
  193. /// <summary>
  194. /// Blur iteration number. A larger value increases the blur effect.
  195. /// </summary>
  196. public int numberBlurIterations = 5;
  197. /// <summary>
  198. /// Sigma value. A larger value increases the blur effect.
  199. /// </summary>
  200. public float sigma_ = 0.1f;
  201. /// <summary>
  202. /// Current sigma value.
  203. /// </summary>
  204. private float currentSigma = -1;
  205. /// <summary>
  206. /// Weights for blur effect.
  207. /// </summary>
  208. private float[] weights_ = new float[5];
  209. /// <summary>
  210. /// Offsets for blur effect.
  211. /// </summary>
  212. private float[] offsets_ = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f };
  213. /// <summary>
  214. /// Material used to convert an RGBA texture into YUV, which makes it simpler to add certain effects.
  215. /// </summary>
  216. public Material matYUV;
  217. /// <summary>
  218. /// Reference to the currently active GarbageMatte.
  219. /// We make an empty one regardless of the enableGarbageMatte setting so a reference to one is always available.
  220. /// </summary>
  221. [SerializeField]
  222. [HideInInspector]
  223. public GarbageMatte garbageMatte = new GarbageMatte();
  224. /// <summary>
  225. /// Whether we're using the garbage matte effect or not.
  226. /// </summary>
  227. public bool enableGarbageMatte = false;
  228. /// <summary>
  229. /// All the data for the garbage matte.
  230. /// </summary>
  231. private GarbageMatte.GarbageMatteData garbageMatteData;
  232. /// <summary>
  233. /// Sets all settings to the default values. Called on a new component, and when Reset is clicked.
  234. /// </summary>
  235. public void SetDefaultValues()
  236. {
  237. keyColors = defaultColor;
  238. smoothness = defaultSmoothness;
  239. range = defaultRange;
  240. spill = defaultSpill;
  241. erosion = defaultErosion;
  242. whiteClip = defaultWhiteClip;
  243. blackClip = defaultBlackClip;
  244. sigma_ = defaultSigma;
  245. }
  246. /// <summary>
  247. /// Cached property id for _MaskTex. use the maskTexID property instead.
  248. /// </summary>
  249. private int? _masktexid;
  250. /// <summary>
  251. /// Property id for _MaskTex, which is the RenderTexture property for the mask texture.
  252. /// </summary>
  253. private int maskTexID
  254. {
  255. get
  256. {
  257. if (_masktexid == null) _masktexid = Shader.PropertyToID("_MaskTex");
  258. return (int)_masktexid;
  259. }
  260. }
  261. /// <summary>
  262. /// Cached property id for weights. use the weightsID property instead.
  263. /// </summary>
  264. private int? _weightsid;
  265. /// <summary>
  266. /// Property id for weights, which affects post-processing blurring.
  267. /// </summary>
  268. private int weightsID
  269. {
  270. get
  271. {
  272. if (_masktexid == null) _masktexid = Shader.PropertyToID("weights");
  273. return (int)_masktexid;
  274. }
  275. }
  276. /// <summary>
  277. /// Cached property id for offset. use the offsetID property instead.
  278. /// </summary>
  279. private int? _offsetid;
  280. /// <summary>
  281. /// Property id for offset, which affects post-processing blurring.
  282. /// </summary>
  283. private int offsetID
  284. {
  285. get
  286. {
  287. if (_offsetid == null) _offsetid = Shader.PropertyToID("offset");
  288. return (int)_offsetid;
  289. }
  290. }
  291. private void OnEnable()
  292. {
  293. //cameraManager = gameObject.GetComponent<ZEDManager> ();
  294. cameraManager = gameObject.GetComponentInParent<ZEDManager>();
  295. if (!cameraManager)
  296. {
  297. //cameraManager = ZEDManager.GetInstance(sl.ZED_CAMERA_ID.CAMERA_ID_01);
  298. cameraManager = FindObjectOfType<ZEDManager>();
  299. }
  300. cameraManager.OnZEDReady += ZEDReady;
  301. Shader.SetGlobalInt("ZEDGreenScreenActivated", 1);
  302. screenManager = GetComponent<ZEDRenderingPlane>();
  303. }
  304. private void OnDisable()
  305. {
  306. if (cameraManager)
  307. {
  308. cameraManager.OnZEDReady -= ZEDReady;
  309. }
  310. }
  311. private void Awake()
  312. {
  313. //cameraManager = gameObject.GetComponent<ZEDManager> ();
  314. Shader.SetGlobalInt("_ZEDStencilComp", 0);
  315. if (screen == null)
  316. {
  317. screen = gameObject.transform.GetChild(0).gameObject;
  318. finalMat = screen.GetComponent<Renderer>().material;
  319. }
  320. if (enableGarbageMatte)
  321. {
  322. garbageMatte = new GarbageMatte(cameraManager, finalMat, transform, garbageMatte);
  323. }
  324. #if ZED_HDRP || ZED_URP
  325. cam = GetComponent<Camera>();
  326. if (!cam) Debug.LogError("GreenScreenManager is not attached to a Camera.");
  327. RenderPipelineManager.beginCameraRendering += OnSRPPreRender;
  328. #endif
  329. #if !UNITY_EDITOR
  330. Debug.Log("Load Chroma keys");
  331. LoadGreenScreenData();
  332. UpdateShader();
  333. CreateFileWatcher("");
  334. #endif
  335. }
  336. /// <summary>
  337. /// Holds whether we need to apply the DEPTH_ALPHA keyword to the ZED imagefirst pass material (Mat_ZED_Forward)
  338. /// which causes it to process the greenscreen mask.
  339. /// </summary>
  340. private bool textureOverlayInit = false;
  341. private void Update()
  342. {
  343. if (screenManager != null && !textureOverlayInit) //Need to tell the shader to apply the mask.
  344. {
  345. if (screenManager.ManageKeywordForwardMat(true, "DEPTH_ALPHA"))
  346. {
  347. textureOverlayInit = true;
  348. }
  349. }
  350. if (toUpdateConfig) //Need to load available greenscreen configuration data into the current, active data.
  351. {
  352. toUpdateConfig = false;
  353. LoadGreenScreenData();
  354. }
  355. if (enableGarbageMatte) //Set up the garbage matte if needed.
  356. {
  357. if (garbageMatte != null && garbageMatte.IsInit)
  358. {
  359. garbageMatte.Update();
  360. }
  361. else
  362. {
  363. if (cameraManager != null)
  364. garbageMatte = new GarbageMatte(cameraManager, finalMat, transform, garbageMatte);
  365. }
  366. }
  367. }
  368. /// <summary>
  369. /// Initialization logic that must be done after the ZED camera has finished initializing.
  370. /// Added to the ZEDManager.OnZEDReady() callback in OnEnable().
  371. /// </summary>
  372. private void ZEDReady()
  373. {
  374. //Set up textures and materials used for the final output.
  375. if (cameraManager == null)
  376. return;
  377. //We set the material again in case it has changed.
  378. //screen = gameObject.transform.GetChild(0).gameObject;
  379. finalMat = screenManager.matRGB;
  380. finalTexture = new RenderTexture(cameraManager.zedCamera.ImageWidth, cameraManager.zedCamera.ImageHeight, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
  381. if (screenManager.forwardMat) screenManager.forwardMat.SetTexture("ZEDMaskTexGreenScreen", finalTexture);
  382. if (screenManager.deferredMat) screenManager.deferredMat.SetTexture("ZEDMaskTexGreenScreen", finalTexture);
  383. finalMat.SetTexture("_MaskTex", finalTexture);
  384. greenScreenMat = new Material(Resources.Load("Materials/Mat_ZED_Compute_GreenScreen") as Material);
  385. blurMaterial = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_Blur") as Material);
  386. matYUV = new Material(Resources.Load("Materials/Mat_ZED_YUV") as Material);
  387. matYUV.SetInt("_isLinear", System.Convert.ToInt32(QualitySettings.activeColorSpace));
  388. preprocessMat = new Material(Resources.Load("Materials/Mat_ZED_Preprocess") as Material);
  389. preprocessMat.SetTexture("_CameraTex", screenManager.TextureEye);
  390. ZEDPostProcessingTools.ComputeWeights(1, out weights_, out offsets_);
  391. //Send the values to the current shader.
  392. blurMaterial.SetFloatArray("weights2", weights_);
  393. blurMaterial.SetFloatArray("offset2", offsets_);
  394. greenScreenMat.SetTexture("_CameraTex", screenManager.TextureEye);
  395. UpdateShader();
  396. UpdateCanal();
  397. if (System.IO.File.Exists("ZED_Settings.conf"))
  398. {
  399. cameraManager.zedCamera.LoadCameraSettings("ZED_Settings.conf");
  400. cameraManager.zedCamera.SetCameraSettings();
  401. }
  402. }
  403. /// <summary>
  404. /// Update the current canal (VIEW) to the setting in the editor.
  405. /// The greenscreen shader uses #ifdef keywords to render differently depending on the active canal.
  406. /// This class makes sure that exactly one such keyword is defined at one time.
  407. /// </summary>
  408. public void UpdateCanal()
  409. {
  410. foreach (CANAL c in System.Enum.GetValues(typeof(CANAL))) //Clear all keywords
  411. {
  412. manageKeyWord(false, c.ToString());
  413. }
  414. if (screenManager != null)
  415. {
  416. //Set NO_DEPTH keyword as well if set to BACKGROUND.
  417. if (canal == CANAL.BACKGROUND) screenManager.ManageKeywordForwardMat(true, "NO_DEPTH");
  418. else screenManager.ManageKeywordForwardMat(false, "NO_DEPTH");
  419. manageKeyWord(true, canal.ToString()); //Activate the keyword corresponding to the current Canal.
  420. }
  421. }
  422. /// <summary>
  423. /// Enables or disables a shader keyword in the finalMat material.
  424. /// </summary>
  425. /// <param name="value"></param>
  426. /// <param name="name"></param>
  427. void manageKeyWord(bool value, string name)
  428. {
  429. if (finalMat != null)
  430. {
  431. if (value)
  432. {
  433. finalMat.EnableKeyword(name);
  434. }
  435. else
  436. {
  437. finalMat.DisableKeyword(name);
  438. }
  439. }
  440. }
  441. #if UNITY_EDITOR
  442. private void OnValidate() //When the Inspector is visible and it changes somehow.
  443. {
  444. UpdateShader();
  445. }
  446. #endif
  447. private void OnApplicationQuit()
  448. {
  449. if (finalTexture != null && finalTexture.IsCreated()) finalTexture.Release();
  450. }
  451. public void Reset() //When the Unity editor Reset button is used.
  452. {
  453. cameraManager = gameObject.GetComponentInParent<ZEDManager>();
  454. if (!cameraManager)
  455. {
  456. cameraManager = ZEDManager.GetInstance(sl.ZED_CAMERA_ID.CAMERA_ID_01);
  457. }
  458. if (cameraManager != null)
  459. {
  460. cameraManager.resolution = sl.RESOLUTION.HD1080;
  461. Debug.Log("Resolution set to HD1080 for better result");
  462. }
  463. SetDefaultValues();
  464. }
  465. /// <summary>
  466. /// Helper function to convert colors in RGB color space to YUV format.
  467. /// </summary>
  468. /// <param name="rgb">Color to be converted.</param>
  469. /// <param name="clamped">Whether to keep the values within the maximum.</param>
  470. /// <returns></returns>
  471. Vector3 RGBtoYUV(Color rgb, bool clamped = true)
  472. {
  473. double Y = 0.182586f * rgb.r + 0.614231f * rgb.g + 0.062007f * rgb.b + 0.062745f; // Luma
  474. double U = -0.100644f * rgb.r - 0.338572f * rgb.g + 0.439216f * rgb.b + 0.501961f; // Delta Blue
  475. double V = 0.439216f * rgb.r - 0.398942f * rgb.g - 0.040274f * rgb.b + 0.501961f; // Delta Red
  476. if (!clamped)
  477. {
  478. U = -0.100644 * rgb.r - 0.338572 * rgb.g + 0.439216 * rgb.b; // Delta Blue
  479. V = 0.439216 * rgb.r - 0.398942 * rgb.g - 0.040274 * rgb.b; // Delta Red
  480. }
  481. return new Vector3((float)Y, (float)U, (float)V);
  482. }
  483. /// <summary>
  484. /// Update all the data to the greenscreen shader.
  485. /// The weights and offsets will be set when sigma changes.
  486. /// </summary>
  487. public void UpdateShader()
  488. {
  489. if (greenScreenMat != null)
  490. {
  491. greenScreenMat.SetVector("_keyColor", RGBtoYUV(keyColors));
  492. greenScreenMat.SetFloat("_range", range);
  493. preprocessMat.SetFloat("_erosion", erosion);
  494. preprocessMat.SetFloat("_smoothness", smoothness);
  495. preprocessMat.SetFloat("_whiteClip", whiteClip);
  496. preprocessMat.SetFloat("_blackClip", blackClip);
  497. preprocessMat.SetFloat("_spill", spill);
  498. preprocessMat.SetColor("_keyColor", keyColors);
  499. }
  500. }
  501. /// <summary>
  502. /// Load the data from a file and fills a structure.
  503. /// </summary>
  504. /// <returns>Whether there's a valid file where pathFileConfig says there is.</returns>
  505. private bool LoadData(out GreenScreenData gsData)
  506. {
  507. gsData = new GreenScreenData();
  508. if (File.Exists(pathFileConfig))
  509. {
  510. string dataAsJson = File.ReadAllText(pathFileConfig);
  511. gsData = JsonUtility.FromJson<GreenScreenData>(dataAsJson);
  512. return true;
  513. }
  514. return false;
  515. }
  516. /// <summary>
  517. /// Creates a new serializable ChromaKeyData file from the current settings.
  518. /// </summary>
  519. public ChromaKeyData RegisterDataChromaKeys()
  520. {
  521. ChromaKeyData chromaKeyData = new ChromaKeyData();
  522. chromaKeyData.chromaKeys = new ChromaKey();
  523. chromaKeyData.erosion = erosion;
  524. chromaKeyData.blurPower = sigma_;
  525. chromaKeyData.numberBlurIterations = numberBlurIterations;
  526. chromaKeyData.whiteClip = whiteClip;
  527. chromaKeyData.spill = spill;
  528. chromaKeyData.blackClip = blackClip;
  529. chromaKeyData.chromaKeys.color = keyColors;
  530. chromaKeyData.chromaKeys.smoothness = smoothness;
  531. chromaKeyData.chromaKeys.range = range;
  532. return chromaKeyData;
  533. }
  534. /// <summary>
  535. /// Saves the chroma keys used in a file (JSON format).
  536. /// </summary>
  537. public void SaveData(ChromaKeyData chromaKeyData, GarbageMatte.GarbageMatteData garbageMatteData)
  538. {
  539. GreenScreenData gsData = new GreenScreenData();
  540. gsData.chromaKeyData = chromaKeyData;
  541. gsData.garbageMatteData = garbageMatteData;
  542. string dataAsJson = JsonUtility.ToJson(gsData);
  543. File.WriteAllText(pathFileConfig, dataAsJson);
  544. }
  545. /// <summary>
  546. /// Fills the current chroma keys with the data from a file.
  547. /// </summary>
  548. public void LoadGreenScreenData(bool forcegarbagemate = false)
  549. {
  550. GreenScreenData gsData;
  551. if (LoadData(out gsData))
  552. {
  553. ChromaKeyData chromaKeyData = gsData.chromaKeyData;
  554. garbageMatteData = gsData.garbageMatteData;
  555. erosion = chromaKeyData.erosion;
  556. sigma_ = chromaKeyData.blurPower;
  557. numberBlurIterations = chromaKeyData.numberBlurIterations;
  558. whiteClip = chromaKeyData.whiteClip;
  559. blackClip = chromaKeyData.blackClip;
  560. spill = chromaKeyData.spill;
  561. keyColors = chromaKeyData.chromaKeys.color;
  562. smoothness = chromaKeyData.chromaKeys.smoothness;
  563. range = chromaKeyData.chromaKeys.range;
  564. }
  565. UpdateShader();
  566. if (forcegarbagemate && garbageMatte != null)
  567. {
  568. if (!garbageMatte.IsInit && cameraManager != null)
  569. {
  570. garbageMatte = new GarbageMatte(cameraManager, finalMat, transform, garbageMatte);
  571. }
  572. enableGarbageMatte = true;
  573. garbageMatte.LoadData(gsData.garbageMatteData);
  574. garbageMatte.ApplyGarbageMatte();
  575. }
  576. }
  577. #if ZED_HDRP || ZED_URP
  578. /// <summary>
  579. ///
  580. /// </summary>
  581. /// <param name="cam"></param>
  582. private void OnSRPPreRender(ScriptableRenderContext context, Camera renderingcam)
  583. {
  584. if (renderingcam == cam)
  585. {
  586. OnPreRender();
  587. }
  588. }
  589. #endif
  590. /// <summary>
  591. /// Where various image processing effects are applied, including the green screen effect itself.
  592. /// </summary>
  593. private void OnPreRender()
  594. {
  595. if (screenManager.TextureEye == null || screenManager.TextureEye.width == 0) return;
  596. if (canal.Equals(CANAL.FOREGROUND)) return;
  597. RenderTexture tempAlpha = RenderTexture.GetTemporary(finalTexture.width, finalTexture.height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
  598. RenderTexture tempFinalAlpha = RenderTexture.GetTemporary(finalTexture.width, finalTexture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
  599. Graphics.Blit(screenManager.TextureEye, tempAlpha, greenScreenMat);
  600. //preprocessMat.SetTexture("_MaskTex", tempAlpha);
  601. preprocessMat.SetTexture(maskTexID, tempAlpha);
  602. Graphics.Blit(screenManager.TextureEye, tempFinalAlpha, preprocessMat);
  603. //If the sigma has changed, recompute the weights and offsets used by the blur.
  604. if (sigma_ == 0)
  605. {
  606. if (sigma_ != currentSigma)
  607. {
  608. currentSigma = sigma_;
  609. ZEDPostProcessingTools.ComputeWeights(currentSigma, out weights_, out offsets_);
  610. //Send the values to the current shader
  611. //blurMaterial.SetFloatArray("weights", weights_);
  612. blurMaterial.SetFloatArray(weightsID, weights_);
  613. //blurMaterial.SetFloatArray("offset", offsets_);
  614. blurMaterial.SetFloatArray(offsetID, offsets_);
  615. }
  616. ZEDPostProcessingTools.Blur(tempFinalAlpha, finalTexture, blurMaterial, 0, 1, 1);
  617. }
  618. else
  619. {
  620. Graphics.Blit(tempFinalAlpha, finalTexture);
  621. }
  622. //Destroy all the temporary buffers
  623. RenderTexture.ReleaseTemporary(tempAlpha);
  624. RenderTexture.ReleaseTemporary(tempFinalAlpha);
  625. }
  626. /// <summary>
  627. /// Gets a value within a gaussian spread defined by sigma.
  628. /// </summary>
  629. float Gaussian(float x, float sigma)
  630. {
  631. return (1.0f / (2.0f * Mathf.PI * sigma)) * Mathf.Exp(-((x * x) / (2.0f * sigma)));
  632. }
  633. /// <summary>
  634. /// Watch for changes in LastAccess and LastWrite times, and the renaming of files or directories.
  635. /// Used to make sure the path to the config file remains valid.
  636. /// </summary>
  637. /// <param name="path"></param>
  638. public void CreateFileWatcher(string path)
  639. {
  640. if (!File.Exists(pathFileConfig)) return;
  641. FileSystemWatcher watcher = new FileSystemWatcher();
  642. watcher.Path = path;
  643. watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  644. watcher.Filter = Path.GetFileName(pathFileConfig);
  645. watcher.Changed += new FileSystemEventHandler(OnChanged);
  646. watcher.EnableRaisingEvents = true;
  647. }
  648. /// <summary>
  649. /// Event handler for when the path to the config file changes while within the editor.
  650. /// </summary>
  651. private void OnChanged(object source, FileSystemEventArgs e)
  652. {
  653. toUpdateConfig = true;
  654. }
  655. }