12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577 |
- //======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
- using UnityEngine;
- using UnityEngine.Rendering;
- /// <summary>
- /// Responsible for actually mixing the real and virtual images, and displaying them in a
- /// Frame object within the camera rig.
- /// First, it displays the image of the ZED into a quad.
- /// Then, it inserts the depth and normals inside the pipeline
- /// Third, it computes the data for the light and send it to the shaders.
- /// Finally, it post-processes the image, if post-processing is enabled.
- /// </summary>
- [RequireComponent(typeof(Camera))]
- public class ZEDRenderingPlane : MonoBehaviour
- {
- /// <summary>
- /// The rendering mode accepted.
- /// </summary>
- enum ZED_RENDERING_MODE
- {
- FORWARD,
- DEFERRED,
- LAST
- };
- /// <summary>
- /// Which side of the camera (left/right) and whether or not this can be overridden by the camera's stereoTargetEye.
- /// </summary>
- public enum ZED_CAMERA_SIDE
- {
- /// <summary>
- /// Feed from the ZED's left camera. Can be overridden by the camera's stereoTargetEye value.
- /// </summary>
- LEFT,
- /// <summary>
- /// Feed from the ZED's right camera. Can be overridden by the camera's stereoTargetEye value.
- /// </summary>
- RIGHT,
- /// <summary>
- /// Feed from the ZED's left camera. Won't be overridden.
- /// </summary>
- LEFT_FORCE,
- /// <summary>
- /// Feed from the ZED's right camera. Won't be overridden.
- /// </summary>
- RIGHT_FORCE
- }
- /// <summary>
- /// The GameGbject that displays the final textures.
- /// In the ZED_Rig_Mono and ZED_Rig_Stereo prefabs, this is the Frame object that's a child of each camera.
- /// </summary>
- [Tooltip("The GameGbject that displays the final textures. " +
- "In the ZED_Rig_Mono and ZED_Rig_Stereo prefabs, this is the Frame object that's a child of each camera.")]
- public GameObject canvas;
- /// <summary>
- /// Which camera on the ZED the image/depth/etc. comes from.
- /// If set to LEFT or RIGHT, this may be overridden by the camera's stereoTargetEye.
- /// If set to LEFT_FORCE or RIGHT_FORCE, it will not be changed.
- /// </summary>
- [Tooltip("Which camera on the ZED the image/depth/etc. comes from.\r\n" +
- "If set to LEFT or RIGHT, this may be overridden by the camera's stereoTargetEye.\r\n" +
- "If set to LEFT_FORCE or RIGHT_FORCE, it will not be changed.")]
- public ZED_CAMERA_SIDE viewSide = ZED_CAMERA_SIDE.LEFT;
- /// <summary>
- /// The main material, set to the one on the canvas's MeshRenderer. Used to set the color and depth.
- /// </summary>
- public Material matRGB { get; private set; }
- /// <summary>
- /// Aspect ratio of the textures. All the textures displayed should be in 16:9.
- /// </summary>
- private float aspect = 16.0f / 9.0f;
- /// <summary>
- /// The Camera component representing an 'eye' of the ZED. Must be on the same GameObject as this component.
- /// </summary>
- private Camera cam;
- /// <summary>
- /// The Camera component representing an 'eye' of the ZED. Must be on the same GameObject as this component.
- /// </summary>
- public Camera renderingCam
- {
- get
- {
- return cam;
- }
- }
- /// <summary>
- /// zedCamera controlled by ZEDManager (one manager controls one camera)
- /// </summary>
- private sl.ZEDCamera zedCamera = null;
- /// <summary>
- /// ZED Manager that controls the zed Camera
- /// </summary>
- private ZEDManager zedManager = null;
- /// <summary>
- /// Texture of the real world generated from the ZED. It may be the from the left or right 'eye.'
- /// Once created, the ZED SDK automatically updates it with each frame/image the ZED captures.
- /// </summary>
- private Texture2D textureEye;
- public Texture2D TextureEye { get { return textureEye; } }
- /// <summary>
- /// Depth generated by the ZEDCamera.
- /// Once created, the ZED SDK automatically updates it whenever the ZED captures new frames/images.
- /// </summary>
- Texture2D depth;
- /// <summary>
- /// Normals generated by the ZEDCamera.
- /// Once created, the ZED SDK automatically updates it whenever the ZED captures new frames/images.
- /// </summary>
- Texture2D normals;
- #if !ZED_HDRP && !ZED_URP
- /// <summary>
- /// CommandBuffer to integrate the depth into Unity's forward or deferred pipeline.
- /// </summary>
- CommandBuffer[] buffer = new CommandBuffer[(int)ZED_RENDERING_MODE.LAST];
- /// <summary>
- /// CommandBuffer to create a mask for the virtual objects in forward and deferred rendering.
- /// </summary>
- CommandBuffer[] postProcessBuffer = new CommandBuffer[(int)ZED_RENDERING_MODE.LAST];
- #endif
- /// <summary>
- /// The material used to integrate the depth in forward mode after the depth texture is created. Mainly used to get the shadows. Not needed for lighting otherwise.
- /// </summary>
- public Material forwardMat { get; private set; }
- /// <summary>
- /// The material used to integrate the depth in deferred mode. Always used in deferred regardless of lighting/shadows.
- /// </summary>
- public Material deferredMat { get; private set; }
- /// <summary>
- /// The actual rendering path used.
- /// To change this, change the settings in Project Settings -> Graphics within the Unity editor.
- /// </summary>
- private RenderingPath actualRenderingPath = RenderingPath.VertexLit;
- public RenderingPath ActualRenderingPath
- {
- get { return actualRenderingPath; }
- }
- /// <summary>
- /// The MeshFilter component of the canvas object. Used to draw the depth buffer.
- /// </summary>
- MeshFilter meshCanvas;
- /// <summary>
- /// A lower resolution of the depth and normals textures from the ZED.
- /// </summary>
- private sl.Resolution resolution = new sl.Resolution(1280, 720);
- /***LIGHTS definitions***/
- /// <summary>
- /// Point light structure for virtual lights on the real world.
- /// Gets sent to the shader via a compute buffer.
- /// </summary>
- [SerializeField]
- public struct PointLight
- {
- /// <summary>
- /// The color, times the intensity.
- /// </summary>
- public Vector4 color;
- /// <summary>
- /// The range of the light.
- /// </summary>
- public float range;
- /// <summary>
- /// The position of the light.
- /// </summary>
- public Vector3 position;
- }
- /// <summary>
- /// Maximum number of point lights accepted.
- /// </summary>
- const int NUMBER_POINT_LIGHT_MAX = 8;
- /// <summary>
- /// Holds a slot for all point lights that should be cast on the real world.
- /// </summary>
- [SerializeField]
- public PointLight[] pointLights = new PointLight[NUMBER_POINT_LIGHT_MAX];
- /// <summary>
- /// The size, or 'stride', of each PointLight in bytes. Needed to construct computeBufferPointLight.
- /// </summary>
- const int SIZE_POINT_LIGHT_BYTES = 32;
- /// <summary>
- /// Used to pass the pointLights array into matRGB's shader as a buffer.
- /// </summary>
- ComputeBuffer computeBufferPointLight;
- /// <summary>
- /// Structure of the spotlight send to the shader
- /// </summary>
- [SerializeField]
- public struct SpotLight
- {
- /// <summary>
- /// The color, times the intensity.
- /// </summary>
- public Vector4 color;
- /// <summary>
- /// The position of the light.
- /// </summary>
- public Vector3 position;
- /// <summary>
- /// The light's normalized direction and angle.
- /// </summary>
- public Vector4 direction;
- /// <summary>
- /// The parameters for the light's falloff.
- /// </summary>
- public Vector4 parameters;
- }
- /// <summary>
- /// Maximum number of spotlights accepted.
- /// </summary>
- const int NUMBER_SPOT_LIGHT_MAX = 8;
- /// <summary>
- /// Holds a slot for all spotlights that should be cast on the real world.
- /// </summary>
- [SerializeField]
- public SpotLight[] spotLights = new SpotLight[NUMBER_SPOT_LIGHT_MAX];
- /// <summary>
- /// The size, or 'stride', of each SpotLight in bytes. Needed to construct computeBufferSpotLight.
- /// </summary>
- const int SIZE_SPOT_LIGHT_BYTES = 60;
- /// <summary>
- /// Maximum number of total lights rendered (point and spot combined).
- /// </summary>
- const int NUMBER_LIGHTS_MAX = NUMBER_POINT_LIGHT_MAX / 2 + NUMBER_SPOT_LIGHT_MAX / 2;
- /// <summary>
- /// Data from a directional light. [0] is its direction and [1] is its color.
- /// Only one directional light is allowed at once.
- /// </summary>
- private Vector4[] directionalLightData = new Vector4[2];
- /// <summary>
- /// Used to pass the spotLights array into matRGB's shader as a buffer.
- /// </summary>
- ComputeBuffer computeBufferSpotLight;
- //Forward ID shader caches.
- /// <summary>
- /// Property ID of the number of point lights in the ZED_Lighting shader include file.
- /// </summary>
- private int numberPointLightsID;
- /// <summary>
- /// Property ID of the number of spotlights in the ZED_Lighting shader include file.
- /// </summary>
- private int numberSpotLightsID;
- /// <summary>
- /// Cached property id for _IsTextured. use isTexturedID property instead.
- /// </summary>
- private int? _istexturedid;
- /// <summary>
- /// Property id for _IsTextured, which is whether the rendered image has a texture overlay.
- /// </summary>
- private int isTexturedID
- {
- get
- {
- if (_istexturedid == null) _istexturedid = Shader.PropertyToID("_IsTextured");
- return (int)_istexturedid;
- }
- }
- /// <summary>
- /// Cached property id for _Mask. use maskPropID property instead.
- /// </summary>
- private int? _maskpropid;
- /// <summary>
- /// Property id for _Mask, which is the RenderTexture property for an overlay texture.
- /// </summary>
- private int maskPropID
- {
- get
- {
- if (_maskpropid == null) _maskpropid = Shader.PropertyToID("_Mask");
- return (int)_maskpropid;
- }
- }
- /*** Post-process definitions***/
- /// <summary>
- /// The mask used for post-processing. Filled at runtime and updated each frame.
- /// </summary>
- private RenderTexture mask;
- /// <summary>
- /// The post process material, used to add noise and change the color.
- /// </summary>
- private Material postprocessMaterial;
- /// <summary>
- /// Activate/deactivate post-processing. If false, the mask will not be generated.
- /// Set by ZEDManager.setRenderingSettings() based on a checkbox in ZEDManager's custom editor.
- /// </summary>
- private bool ARpostProcessing = true;
- /// <summary>
- /// Used to blur the mask.
- /// </summary>
- private Material blurMaterial;
- /// <summary>
- /// Used to load a source image's alpha channel into all channels of a destination image.
- /// Used during post-processing.
- /// </summary>
- private Material blitMaterial;
- /// <summary>
- /// Used to convert the stencil buffer of a rendertexture into a regular texture.
- /// </summary>
- private Material matStencilToMask;
- /// <summary>
- /// Used to compose the virtual mask from different textures.
- /// </summary>
- private Material matComposeMask;
- /// <summary>
- /// Used to blend the textures from ZEDMeshRenderer, when present.
- /// This adds the wireframe effect seen from 3D scanning or plane detection.
- /// </summary>
- private Material blender;
- /// <summary>
- /// What kind of image the final result will display. Usually set to View.
- /// Set this to VIEW_DEPTH or VIEW_NORMAL to see the live depth or normal maps.
- /// </summary>
- public sl.VIEW_MODE viewMode = sl.VIEW_MODE.VIEW_IMAGE;
- /// <summary>
- /// Which side of the camera we render. Left = 0, Right ==1.
- /// </summary>
- private int side
- {
- get
- {
- if (viewSide == ZED_CAMERA_SIDE.LEFT || viewSide == ZED_CAMERA_SIDE.LEFT_FORCE) return 0;
- else return 1;
- }
- }
- /// <summary>
- /// Default near plane value. Overrides camera's settings on start but will update if camera values change at runtime.
- /// </summary>
- private float nearplane = 0.1f;
- /// <summary>
- /// Default far plane value. Overrides camera's settings on start but will update if camera values change at runtime.
- /// </summary>
- private float farplane = 500.0f;
- /// <summary>
- /// The target RenderTexture we'll render to if in AR mode.
- /// </summary>
- [HideInInspector]
- private RenderTexture renderTextureTarget;
- public RenderTexture target
- {
- get { return renderTextureTarget; }
- }
- void Awake()
- {
- //Get the current camera and set the aspect ratio.
- zedManager = gameObject.transform.parent.GetComponent<ZEDManager>();
- cam = GetComponent<Camera>();
- cam.aspect = aspect;
- cam.renderingPath = RenderingPath.UsePlayerSettings; //Assigns the camera's rendering path to be consistent with the project's settings.
- //Make the canvas allow rendering this camera.
- HideFromWrongCameras.RegisterZEDCam(cam); //Makes all objects with a HideFromWrongCamera hide from this, unless set to this specifc one.
- HideFromWrongCameras hider = canvas.GetComponent<HideFromWrongCameras>();
- if (!hider)
- {
- hider = canvas.AddComponent<HideFromWrongCameras>();
- }
- hider.SetRenderCamera(cam); //This canvas will allow this camera to render it.
- }
- /// <summary>
- /// Whether or not post-processing effects are applied.
- /// Usually set by ZEDManager based on the selection in its Inspector.
- /// </summary>
- /// <param name="c"></param>
- public void SetPostProcess(bool c)
- {
- ARpostProcessing = c;
- }
- /// <summary>
- /// The object that forces the ZED image to be shown at 16:9 aspect ratio, regardless of the target window's resolution.
- /// </summary>
- private WindowAspectRatio aspectRatio;
- /// <summary>
- /// Changes the scene's global lighting settings to prevent global illumnation from causing
- /// lighting that doesn't match the real world.
- /// </summary>
- private void SetUpGI()
- {
- //Only do this if "Hide Skybox" is enabled in ZEDManager, which is is by default.
- if (zedManager)
- {
- if (zedManager.greySkybox)
- {
- RenderSettings.skybox = null;
- Color c;
- ColorUtility.TryParseHtmlString("#999999", out c);
- RenderSettings.ambientLight = c;
- DynamicGI.UpdateEnvironment();
- }
- }
- }
- /// <summary>
- /// Configures materials/values/settings needed for post-processing and displaying in proper aspect ratio.
- /// </summary>
- private void Start()
- {
- //No environmental lighting per default
- Shader.SetGlobalFloat("_ZEDExposure", -1);
- //Load the materials.
- matStencilToMask = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_Stencil2Mask") as Material);
- matComposeMask = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_MaskCompositor") as Material);
- //Load and configure the post-process material.
- postprocessMaterial = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_PostProcessing") as Material);
- postprocessMaterial.SetFloat("_gamma", 1.0f / (0.87f * 0.9f));
- postprocessMaterial.SetFloat("_MinBlack", 15.0f / 255.0f);
- postprocessMaterial.SetInt("_NoiseSize", 2);
- //Configure the weights for the blur effect.
- float[] weights;
- float[] offsets;
- ZEDPostProcessingTools.ComputeWeights(0.3f, out weights, out offsets);
- //Set the blur config to the shader, should be constant
- blurMaterial = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_Blur") as Material);
- blurMaterial.SetFloatArray("weights", weights);
- blurMaterial.SetFloatArray("offset", offsets);
- //blurMaterial.SetTexture("_Mask", mask);
- blurMaterial.SetTexture(maskPropID, mask);
- //Force Unity into 16:9 mode to match the ZED's output.
- #if UNITY_EDITOR
- UnityEditor.PlayerSettings.SetAspectRatio(UnityEditor.AspectRatio.Aspect16by9, true);
- UnityEditor.PlayerSettings.SetAspectRatio(UnityEditor.AspectRatio.Aspect16by10, false);
- UnityEditor.PlayerSettings.SetAspectRatio(UnityEditor.AspectRatio.Aspect4by3, false);
- UnityEditor.PlayerSettings.SetAspectRatio(UnityEditor.AspectRatio.Aspect5by4, false);
- #endif
- CreateRenderTexture();
- //Load the blender for the zedmesher
- blender = new Material(Resources.Load("Materials/SpatialMapping/Mat_ZED_PostProcess_Blend") as Material);
- SetMeshRenderAvailable(false);
- //Set the bounds around the camera, used to detect if a point/spotlight is close enough to be applied.
- bounds = new Bounds(transform.position, new Vector3(20, 20, 20));
- //IF AR REMOVE
- //aspectRatio = new WindowAspectRatio(cam);
- #if ZED_LWRP || ZED_HDRP || ZED_URP
- RenderPipelineManager.beginFrameRendering += SRPStartFrame;
- #endif
- }
- /// <summary>
- /// Configures numerous settings that can't be set until the ZED is fully initialized.
- /// Subscribed to ZEDManager.OnZEDReady in OnEnable().
- /// </summary>
- void ZEDReady()
- {
- //Add the fade-in effect for when the camera first becomes visible.
- if (zedManager.fadeInOnStart)
- gameObject.AddComponent<LoadingFade>();
- //This cannot happen but just in case...
- if (zedManager == null)
- return;
- zedCamera = zedManager.zedCamera;
- SetTextures(zedCamera, viewMode);
- canvas.SetActive(true);
- canvas.transform.SetParent(cam.transform);
- ConfigureLightAndShadow(cam.actualRenderingPath);
- //Move the plane with the optical centers.
- float plane_distance = 0.15f;
- Vector4 opticalCenters = zedCamera.ComputeOpticalCenterOffsets(plane_distance);
- if (side == 0)
- canvas.transform.localPosition = new Vector3(opticalCenters.x, -1.0f * opticalCenters.y, plane_distance);
- else if (side == 1)
- canvas.transform.localPosition = new Vector3(opticalCenters.z, -1.0f * opticalCenters.w, plane_distance);
- //Set the camera's parameters based on the ZED's, and scale the screen based on its distance.
- if (zedCamera.IsCameraReady)
- {
- //cam.projectionMatrix = zedCamera.Projection;
- SetProjection(nearplane, farplane);
- cam.nearClipPlane = nearplane;
- cam.farClipPlane = farplane;
- //mainCamera.nearClipPlane = 0.1f;
- //mainCamera.farClipPlane = 500.0f;
- scale(canvas.gameObject, GetFOVYFromProjectionMatrix(cam.projectionMatrix));
- cam.fieldOfView = zedCamera.VerticalFieldOfView * Mathf.Rad2Deg;
- }
- else //Just scale the screen.
- {
- scale(canvas.gameObject, cam.fieldOfView);
- }
- }
- /// <summary>
- /// Hides the canvas. Called when the ZED is disconnected via the ZEDManager.OnZEDDisconnected event.
- /// </summary>
- void ZEDDisconnected()
- {
- canvas.SetActive(false);
- }
- /// <summary>
- /// Fixes GI, enables the canvas and subscribes to events from the ZED.
- /// </summary>
- private void OnEnable()
- {
- SetUpGI();
- meshCanvas = gameObject.transform.GetChild(0).GetComponent<MeshFilter>();
- canvas.SetActive(false);
- //iterate until we found the ZED Manager parent...
- Transform ObjParent = gameObject.transform;
- int tries = 0;
- while (zedManager == null && tries < 5)
- {
- if (ObjParent != null)
- zedManager = ObjParent.GetComponent<ZEDManager>();
- if (zedManager == null && ObjParent != null)
- ObjParent = ObjParent.parent;
- tries++;
- }
- if (zedManager != null)
- {
- zedManager.OnZEDReady += ZEDReady;
- zedManager.OnZEDDisconnected += ZEDDisconnected;
- }
- #if ZED_HDRP
- //Check which material the ZEDManager's SRP Lighting Type wants us to use, then apply it.
- Renderer rend = canvas.GetComponent<Renderer>();
- Material basemattoapply;
- bool changemat = zedManager.GetChosenSRPMaterial(out basemattoapply);
- if (changemat) //A specific material has been specified. Apply that one.
- {
- matRGB = new Material(basemattoapply); //We make a new instance so we can apply different textures to the left/right eye, and different cameras.
- }
- else //We'll leave whatever material is already on the canvas.
- {
- matRGB = new Material(rend.material);
- }
- rend.material = matRGB;
- #endif
- }
- /// <summary>
- /// Disables the canvas and unsubscribes from events from the ZED.
- /// </summary>
- private void OnDisable()
- {
- if (zedManager != null)
- {
- zedManager.OnZEDReady -= ZEDReady;
- zedManager.OnZEDDisconnected -= ZEDDisconnected;
- }
- canvas.SetActive(false);
- }
- /// <summary>
- /// Invisible object used to force Unity to render a shadow map.
- /// </summary>
- GameObject forceShadowObject = null;
- /// <summary>
- /// Configure the canvas to get and light and shadow.
- /// </summary>
- /// <param name="renderingPath">The current rendering path used</param>
- private void ConfigureLightAndShadow(RenderingPath renderingPath)
- {
- RenderingPath current = actualRenderingPath;
- actualRenderingPath = renderingPath;
- if (renderingPath == RenderingPath.Forward)
- {
- canvas.SetActive(true);
- SetForward();
- }
- else if (renderingPath == RenderingPath.DeferredShading)
- {
- SetDeferred();
- }
- else //We're using an unknown rendering path. Log an error.
- {
- actualRenderingPath = current;
- Debug.LogError(" [ ZED Plugin ] : The rendering path " + cam.actualRenderingPath.ToString() + " is not compatible with the ZED");
- }
- }
- #if !ZED_HDRP && !ZED_URP
- /// <summary>
- /// Clear the depth buffer used.
- /// Called when configuring this script for the given rendering path (forward or deferred).
- /// </summary>
- private void ClearDepthBuffers()
- {
- if (buffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- {
- buffer[(int)ZED_RENDERING_MODE.FORWARD].Dispose();
- buffer[(int)ZED_RENDERING_MODE.FORWARD] = null;
- }
- if (buffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- {
- buffer[(int)ZED_RENDERING_MODE.DEFERRED].Dispose();
- buffer[(int)ZED_RENDERING_MODE.DEFERRED] = null;
- }
- }
- #endif
- /// <summary>
- /// Configure the materials and buffer for the forward rendering path.
- /// </summary>
- private void SetForward()
- {
- ghasShadows = false;
- blitMaterial = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_Blit") as Material);
- Shader.SetGlobalInt("_HasShadows", 0);
- gameObject.transform.GetChild(0).GetComponent<MeshRenderer>().enabled = true;
- //Set the canvas's material to the material for forward rendering.
- matRGB = canvas.GetComponent<Renderer>().material;
- matRGB.SetInt("_isLinear", System.Convert.ToInt32(QualitySettings.activeColorSpace));
- forwardMat = new Material(Resources.Load("Materials/Lighting/Mat_ZED_Forward") as Material);
- // Configure the invisible object that forces Unity to calculate shadows.
- if (forceShadowObject == null)
- {
- ConfigureForceShadowObject();
- }
- //Set the textures in the materials to the proper ones.
- matRGB.SetTexture("_MainTex", textureEye);
- matRGB.SetTexture("_CameraTex", textureEye);
- matRGB.SetTexture("_DepthXYZTex", depth);
- matRGB.SetTexture("_NormalsTex", normals);
- #if ZED_HDRP && !ZED_URP//Need FoV to calculate world space positions accurately.
- matRGB.SetFloat("_ZEDHFoVRad", zedCamera.GetCalibrationParameters().leftCam.hFOV * Mathf.Deg2Rad);
- matRGB.SetFloat("_ZEDVFoVRad", zedCamera.GetCalibrationParameters().leftCam.vFOV * Mathf.Deg2Rad);
- #endif
- forwardMat.SetTexture("_MainTex", textureEye);
- forwardMat.SetTexture("_DepthXYZTex", depth);
- #if !ZED_HDRP && !ZED_URP
- //Clear the buffers.
- if (buffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- cam.RemoveCommandBuffer(CameraEvent.BeforeDepthTexture, buffer[(int)ZED_RENDERING_MODE.FORWARD]);
- if (buffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterGBuffer, buffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- ClearDepthBuffers();
- if (postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterFinalPass, postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- if (postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- {
- postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED].Dispose();
- postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED] = null;
- }
- //Set the depth buffer.
- buffer[(int)ZED_RENDERING_MODE.FORWARD] = new CommandBuffer();
- buffer[(int)ZED_RENDERING_MODE.FORWARD].name = "ZED_DEPTH";
- buffer[(int)ZED_RENDERING_MODE.FORWARD].SetRenderTarget(BuiltinRenderTextureType.CurrentActive);
- buffer[(int)ZED_RENDERING_MODE.FORWARD].DrawMesh(meshCanvas.mesh, gameObject.transform.GetChild(0).transform.localToWorldMatrix, forwardMat);
- #endif
- if (mask == null || !mask.IsCreated())
- {
- mask = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.R8);
- }
- //Set up the post-processing material.
- postprocessMaterial.SetTexture("ZEDMaskPostProcess", mask);
- postprocessMaterial.SetTexture("ZEDTex", textureEye);
- #if !ZED_HDRP && !ZED_URP
- postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD] = new CommandBuffer();
- postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD].name = "ZED_FORWARD_POSTPROCESS";
- postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD].Blit(BuiltinRenderTextureType.CameraTarget, mask, blitMaterial, 0);
- postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD].SetGlobalTexture("_ZEDMaskVirtual", mask);
- cam.RemoveCommandBuffer(CameraEvent.AfterForwardAlpha, postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD]);
- cam.AddCommandBuffer(CameraEvent.AfterForwardAlpha, postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD]);
- #endif
- //Configure the light containers.
- if (computeBufferPointLight == null)
- {
- computeBufferPointLight = new ComputeBuffer(NUMBER_POINT_LIGHT_MAX, SIZE_POINT_LIGHT_BYTES);
- computeBufferPointLight.SetData(pointLights);
- matRGB.SetBuffer("pointLights", computeBufferPointLight);
- }
- if (computeBufferSpotLight == null)
- {
- computeBufferSpotLight = new ComputeBuffer(NUMBER_SPOT_LIGHT_MAX, SIZE_SPOT_LIGHT_BYTES);
- computeBufferSpotLight.SetData(spotLights);
- matRGB.SetBuffer("spotLights", computeBufferSpotLight);
- }
- //Register the property IDs to improve performance. (Setting properties by string is slower)
- numberPointLightsID = Shader.PropertyToID("numberPointLights");
- numberSpotLightsID = Shader.PropertyToID("numberSpotLights");
- }
- /// <summary>
- /// Configure the materials and buffer for the deferred rendering path.
- /// </summary>
- private void SetDeferred()
- {
- //Disable MSSA as it's not supported with deferred.
- #if UNITY_5_6_OR_NEWER
- cam.allowMSAA = false;
- #endif
- ghasShadows = false;
- deferredMat = new Material(Resources.Load("Materials/Lighting/Mat_ZED_Deferred") as Material);
- blitMaterial = new Material(Resources.Load("Materials/PostProcessing/Mat_ZED_Blit") as Material);
- //Sets the custom shader for the deferred pipeline.
- GraphicsSettings.SetCustomShader(BuiltinShaderType.DeferredShading, (Resources.Load("Materials/Lighting/Mat_ZED_Deferred_Lighting") as Material).shader);
- deferredMat.SetMatrix("_Model", canvas.transform.localToWorldMatrix.transpose);
- deferredMat.SetMatrix("_Projection", cam.projectionMatrix);
- deferredMat.SetTexture("_MainTex", textureEye);
- deferredMat.SetTexture("_DepthXYZTex", depth);
- deferredMat.SetTexture("_NormalsTex", normals);
- //Clear the buffers.
- #if !ZED_HDRP && !ZED_URP
- if (buffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- cam.RemoveCommandBuffer(CameraEvent.BeforeDepthTexture, buffer[(int)ZED_RENDERING_MODE.FORWARD]);
- if (buffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterGBuffer, buffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- if (postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterForwardAlpha, postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD]);
- if (postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- {
- postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD].Dispose();
- postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD] = null;
- }
- ClearDepthBuffers();
- //Set the depths buffer. This buffer will be changed if the camera is set to allow HDR.
- buffer[(int)ZED_RENDERING_MODE.DEFERRED] = new CommandBuffer();
- buffer[(int)ZED_RENDERING_MODE.DEFERRED].name = "ZED_DEPTH";
- if (cam.allowHDR)
- {
- RenderTargetIdentifier[] mrt = { BuiltinRenderTextureType.GBuffer0, BuiltinRenderTextureType.GBuffer1, BuiltinRenderTextureType.GBuffer2, BuiltinRenderTextureType.CameraTarget };
- buffer[(int)ZED_RENDERING_MODE.DEFERRED].SetRenderTarget(mrt, BuiltinRenderTextureType.CameraTarget);
- }
- else
- {
- RenderTargetIdentifier[] mrt = { BuiltinRenderTextureType.GBuffer0, BuiltinRenderTextureType.GBuffer1, BuiltinRenderTextureType.GBuffer2, BuiltinRenderTextureType.GBuffer3 };
- buffer[(int)ZED_RENDERING_MODE.DEFERRED].SetRenderTarget(mrt, BuiltinRenderTextureType.CameraTarget);
- }
- buffer[(int)ZED_RENDERING_MODE.DEFERRED].DrawMesh(meshCanvas.mesh, gameObject.transform.GetChild(0).transform.localToWorldMatrix, deferredMat);
- if (mask == null || !mask.IsCreated())
- {
- mask = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.R8);
- }
- //Set the post process buffer
- postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED] = new CommandBuffer();
- postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED].name = "ZED_FORWARD_POSTPROCESS";
- postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED].Blit(BuiltinRenderTextureType.GBuffer0, mask, blitMaterial, 0);
- postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED].SetGlobalTexture("_ZEDMaskVirtual", mask);
- postprocessMaterial.SetTexture("ZEDMaskPostProcess", mask);
- postprocessMaterial.SetTexture("ZEDTex", textureEye);
- cam.AddCommandBuffer(CameraEvent.AfterGBuffer, buffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- cam.AddCommandBuffer(CameraEvent.AfterFinalPass, postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- #endif
- //Congigure the invisible object
- if (forceShadowObject == null)
- {
- ConfigureForceShadowObject();
- }
- transform.GetChild(0).GetComponent<MeshRenderer>().enabled = false;
- }
- /// <summary>
- /// Sets up the invisible shadow GameObject that forces Unity to draw shadows.
- /// </summary>
- private void ConfigureForceShadowObject()
- {
- forceShadowObject = GameObject.CreatePrimitive(PrimitiveType.Quad);
- forceShadowObject.name = "ZED_FORCE_SHADOW";
- forceShadowObject.transform.parent = transform;
- forceShadowObject.transform.localPosition = new Vector3(0, 0, cam.nearClipPlane);
- forceShadowObject.GetComponent<MeshRenderer>().sharedMaterial = Resources.Load("Materials/Lighting/Mat_ZED_Hide") as Material;
- Destroy(forceShadowObject.GetComponent<MeshCollider>());
- forceShadowObject.hideFlags = HideFlags.HideInHierarchy;
- }
- /// <summary>
- /// The bounds around the camera that filter out point/spotlights that are too far away to be rendered.
- /// </summary>
- private Bounds bounds;
- /// <summary>
- /// Sets the camera's local pos/rot to origin/identity and sets up the RenderTexture if in stereo mode.
- /// This RenderTexture is then displayed in hidden planes handled by ZEDMixedRealityPlugin where the final
- /// output to the HMD is rendered.
- /// </summary>
- private void CreateRenderTexture()
- {
- transform.localRotation = Quaternion.identity;
- transform.localPosition = new Vector3(0, 0, 0);
- if (cam.stereoTargetEye != StereoTargetEyeMask.None && zedManager.IsStereoRig == true)
- {
- if (zedCamera != null && zedCamera.IsCameraReady)
- {
- renderTextureTarget = new RenderTexture(zedCamera.ImageWidth, zedCamera.ImageHeight, 24, RenderTextureFormat.ARGB32);
- cam.targetTexture = renderTextureTarget;
- }
- else if (sl.ZEDCamera.CheckPlugin())
- {
- renderTextureTarget = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
- cam.targetTexture = renderTextureTarget;
- }
- }
- }
- /// <summary>
- /// Creates and sets the textures from the ZED, including image, depth and normals as needed.
- /// Once created, the ZED SDK updates the textures automatically when the ZED sends new frames, so they don't need to be updated here.
- /// </summary>
- /// <param name="zedCamera"></param>
- private void SetTextures(sl.ZEDCamera zedCamera, sl.VIEW_MODE view_mode)
- {
- float baseline = zedCamera.Baseline;
- canvas.transform.localRotation = Quaternion.identity;
- canvas.transform.localPosition = new Vector3(0, 0, 0);
- if (zedManager.IsStereoRig == true && cam.stereoTargetEye != StereoTargetEyeMask.None)
- {
- if (zedCamera != null && zedCamera.IsCameraReady)
- {
- renderTextureTarget = new RenderTexture(zedCamera.ImageWidth, zedCamera.ImageHeight, 24, RenderTextureFormat.ARGB32);
- cam.targetTexture = renderTextureTarget;
- }
- //Set the camera to match the target stereo eye, unless force otherwise.
- switch (cam.stereoTargetEye)
- {
- case StereoTargetEyeMask.Left:
- if (viewSide == ZED_CAMERA_SIDE.RIGHT) viewSide = ZED_CAMERA_SIDE.LEFT;
- break;
- case StereoTargetEyeMask.Right:
- if (viewSide == ZED_CAMERA_SIDE.LEFT) viewSide = ZED_CAMERA_SIDE.RIGHT;
- break;
- default:
- break;
- }
- }
- switch (viewSide) //Set up textures from the left camera or right camera, depending.
- {
- case ZED_CAMERA_SIDE.LEFT:
- case ZED_CAMERA_SIDE.LEFT_FORCE:
- default:
- switch (view_mode) //Which kind of texture we view.
- {
- case sl.VIEW_MODE.VIEW_IMAGE:
- textureEye = zedCamera.CreateTextureImageType(sl.VIEW.LEFT);
- break;
- case sl.VIEW_MODE.VIEW_DEPTH:
- textureEye = zedCamera.CreateTextureImageType(sl.VIEW.DEPTH);
- break;
- case sl.VIEW_MODE.VIEW_NORMALS:
- textureEye = zedCamera.CreateTextureImageType(sl.VIEW.NORMALS);
- break;
- }
- normals = zedCamera.CreateTextureMeasureType(sl.MEASURE.NORMALS, resolution);
- depth = zedCamera.CreateTextureMeasureType(sl.MEASURE.DEPTH, resolution);
- break;
- case ZED_CAMERA_SIDE.RIGHT:
- case ZED_CAMERA_SIDE.RIGHT_FORCE:
- switch (view_mode)//Which kind of texture we view.
- {
- case sl.VIEW_MODE.VIEW_IMAGE:
- textureEye = zedCamera.CreateTextureImageType(sl.VIEW.RIGHT);
- break;
- case sl.VIEW_MODE.VIEW_DEPTH:
- textureEye = zedCamera.CreateTextureImageType(sl.VIEW.DEPTH_RIGHT);
- break;
- case sl.VIEW_MODE.VIEW_NORMALS:
- textureEye = zedCamera.CreateTextureImageType(sl.VIEW.NORMALS_RIGHT);
- break;
- }
- normals = zedCamera.CreateTextureMeasureType(sl.MEASURE.NORMALS_RIGHT, resolution);
- depth = zedCamera.CreateTextureMeasureType(sl.MEASURE.DEPTH_RIGHT, resolution);
- break;
- }
- }
- /// <summary>
- /// Enables/disables keywords for the material used in the first pass, when in forward rendering.
- /// </summary>
- /// <param name="enable">New state of the keyword.</param>
- /// <param name="name">Keyword's name.</param>
- /// <returns></returns>
- public bool ManageKeywordForwardMat(bool enable, string name)
- {
- if (forwardMat)
- {
- if (enable)
- {
- forwardMat.EnableKeyword(name);
- }
- else
- {
- forwardMat.DisableKeyword(name);
- }
- return true;
- }
- return false;
- }
- /// <summary>
- /// Enables/disables keywords for the material used in the first pass, when in deferred rendering.
- /// </summary>
- /// <param name="enable">New state of the keyword.</param>
- /// <param name="name">Keyword's name.</param>
- /// <returns></returns>
- public bool ManageKeywordDeferredMat(bool enable, string name)
- {
- if (deferredMat)
- {
- if (enable)
- {
- deferredMat.EnableKeyword(name);
- }
- else
- {
- deferredMat.DisableKeyword(name);
- }
- return true;
- }
- return false;
- }
- /// <summary>
- /// Enables/disables keywords for the final display material.
- /// </summary>
- /// <param name="enable">New state of the keyword.</param>
- /// <param name="name">Keyword's name.</param>
- /// <returns></returns>
- public bool ManageKeywordPipe(bool enable, string name)
- {
- if (matRGB)
- {
- if (enable)
- {
- matRGB.EnableKeyword(name);
- }
- else
- {
- matRGB.DisableKeyword(name);
- }
- return true;
- }
- return false;
- }
- //Variables to get information about the lights.
- /// <summary>
- /// How many point lights are currently being rendered on the real world by this camera. Excludes ones filtered out by distance.
- /// </summary>
- [HideInInspector]
- public int numberPointLights;
- /// <summary>
- /// How many spotlights are currently being rendered on the real world by this camera. Excludes ones filtered out by distance.
- /// </summary>
- [HideInInspector]
- public int numberSpotLights;
- bool ghasShadows = false;
- /// <summary>
- /// Updates lighting information, packages them into ComputeBuffers and sends them to the shader.
- /// </summary>
- void UpdateLights()
- {
- bool hasShadows = false;
- int pointLightIndex = 0;
- int spotLightIndex = 0;
- bounds.center = transform.position;
- foreach (ZEDLight zed_light in ZEDLight.s_lights)
- {
- Light light = zed_light.cachedLight;
- if (light.type == LightType.Directional || Vector3.Distance(bounds.center, light.transform.position) < (light.range + bounds.extents.x))
- {
- //Deactivate all shadows from point light and spotlights as they are not currently supported.
- if (light.type != LightType.Directional)
- {
- light.shadows = LightShadows.None;
- }
- if (zed_light.IsEnabled() && ((pointLightIndex + spotLightIndex) < NUMBER_LIGHTS_MAX || light.type == LightType.Directional))
- {
- if (light.type == LightType.Point)
- {
- if (pointLightIndex < NUMBER_POINT_LIGHT_MAX)
- {
- pointLights[pointLightIndex].color = light.color * light.intensity;
- pointLights[pointLightIndex].position = light.gameObject.transform.position;
- pointLights[pointLightIndex].range = light.range;
- pointLightIndex++;
- }
- }
- else if (light.type == LightType.Spot)
- {
- if (spotLightIndex < NUMBER_SPOT_LIGHT_MAX)
- {
- spotLights[spotLightIndex].color = light.color * light.intensity;
- spotLights[spotLightIndex].position = light.gameObject.transform.position;
- spotLights[spotLightIndex].direction = new Vector4(light.gameObject.transform.forward.normalized.x, light.gameObject.transform.forward.normalized.y, light.gameObject.transform.forward.normalized.z, Mathf.Cos((light.spotAngle / 2.0f) * Mathf.Deg2Rad));
- spotLights[spotLightIndex].parameters = new Vector4(light.spotAngle, light.intensity, 1.0f / light.range, zed_light.interiorCone);
- spotLightIndex++;
- }
- }
- else if (light.type == LightType.Directional)
- {
- hasShadows = light.shadows != LightShadows.None && QualitySettings.shadows != ShadowQuality.Disable;
- directionalLightData[0] = new Vector4(light.gameObject.transform.forward.normalized.x, light.gameObject.transform.forward.normalized.y, light.gameObject.transform.forward.normalized.z, 0);
- directionalLightData[1] = light.color * light.intensity;
- // Copy the shadows from the directional light. If not, no shadows in transparent mode.
- if (light.commandBufferCount == 0)
- {
- forwardMat.SetInt("_HasShadows", System.Convert.ToInt32(light.shadows != LightShadows.None));
- // Copy the shadows from the directional light. If not, no shadows in transparent mode.
- if (light.commandBufferCount == 0)
- {
- CommandBuffer lightBuffer = new CommandBuffer();
- lightBuffer.name = "ZED_Copy_ShadowMap";
- lightBuffer.SetGlobalTexture("_DirectionalShadowMap", BuiltinRenderTextureType.CurrentActive);
- light.AddCommandBuffer(LightEvent.AfterScreenspaceMask, lightBuffer);
- }
- }
- }
- }
- }
- }
- //Send the new light data to the final display material.
- if (computeBufferPointLight != null)
- {
- computeBufferPointLight.SetData(pointLights);
- }
- if (computeBufferSpotLight != null)
- {
- computeBufferSpotLight.SetData(spotLights);
- }
- numberPointLights = pointLightIndex;
- numberSpotLights = spotLightIndex;
- if (matRGB != null)
- {
- //Send the number of point lights/spotlights to the shader.
- matRGB.SetInt(numberPointLightsID, pointLightIndex);
- matRGB.SetInt(numberSpotLightsID, spotLightIndex);
- #if !ZED_HDRP && !ZED_URP
- //Add the command buffer to get shadows only if a directional light creates shadows.
- if (hasShadows != ghasShadows)
- {
- ghasShadows = hasShadows;
- Shader.SetGlobalInt("_HasShadows", System.Convert.ToInt32(ghasShadows));
- cam.RemoveCommandBuffer(CameraEvent.BeforeDepthTexture, buffer[(int)ZED_RENDERING_MODE.FORWARD]);
- if (hasShadows)
- {
- cam.AddCommandBuffer(CameraEvent.BeforeDepthTexture, buffer[(int)ZED_RENDERING_MODE.FORWARD]);
- }
- }
- matRGB.SetVectorArray("ZED_directionalLight", directionalLightData);
- #endif
- }
- }
- /// <summary>
- /// Gets the vertical field of view from the given projection matrix, to bypass a round number.
- /// </summary>
- /// <param name="projection">Projection matrix from a camera.</param>
- /// <returns></returns>
- float GetFOVYFromProjectionMatrix(Matrix4x4 projection)
- {
- return Mathf.Atan(1 / projection[1, 1]) * 2.0f;
- }
- /// <summary>
- /// Gets the horizontal field of view from the given projection matrix.
- /// </summary>
- /// <param name="projection">Projection matrix from a camera.</param>
- /// <returns></returns>
- float GetFOVXFromProjectionMatrix(Matrix4x4 projection)
- {
- return Mathf.Atan(1 / projection[0, 0]) * 2.0f;
- }
- /// <summary>
- /// Scales the canvas in front of the camera so that it fills the whole screen exactly.
- /// </summary>
- /// <param name="screen">Canvas object.</param>
- /// <param name="fov">Camera's vertical field of view. </param>
- private void scale(GameObject screen, float fov)
- {
- float height = Mathf.Tan(0.5f * fov) * Vector3.Distance(screen.transform.localPosition, Vector3.zero) * 2;
- screen.transform.localScale = new Vector3((height * aspect), height, 1);
- }
- private void scaleXY(GameObject screen, float fovH, float fovV)
- {
- float height = Mathf.Tan(0.5f * fovV) * Vector3.Distance(screen.transform.localPosition, Vector3.zero) * 2;
- float width = Mathf.Tan(0.5f * fovH) * Vector3.Distance(screen.transform.localPosition, Vector3.zero) * 2;
- screen.transform.localScale = new Vector3(width, height, 1);
- }
- #if !ZED_HDRP && !ZED_URP
- /// <summary>
- /// Clears all command buffers on the camera.
- /// </summary>
- public void Clear()
- {
- if (buffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- cam.RemoveCommandBuffer(CameraEvent.BeforeDepthTexture, buffer[(int)ZED_RENDERING_MODE.FORWARD]);
- if (buffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterGBuffer, buffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- if (postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterForwardAlpha, postProcessBuffer[(int)ZED_RENDERING_MODE.FORWARD]);
- if (postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED] != null)
- cam.RemoveCommandBuffer(CameraEvent.AfterFinalPass, postProcessBuffer[(int)ZED_RENDERING_MODE.DEFERRED]);
- ClearDepthBuffers();
- }
- #endif
- void OnApplicationQuit()
- {
- if (computeBufferPointLight != null)
- {
- computeBufferPointLight.Release();
- }
- if (computeBufferSpotLight != null)
- {
- computeBufferSpotLight.Release();
- }
- if (mask != null)
- {
- mask.Release();
- }
- #if ZED_HDRP || ZED_URP
- RenderPipelineManager.beginFrameRendering -= SRPStartFrame;
- #endif
- }
- /// <summary>
- /// Updates the output size to fit the window at 16:9 and the bounds for light filtering, and calculates the lighting.
- /// </summary>
- void Update()
- {
- if (zedManager == null)
- return;
- if (aspectRatio != null)
- {
- aspectRatio.Update();
- }
- if (actualRenderingPath == RenderingPath.Forward)
- {
- bounds.center = transform.position;
- UpdateLights();
- }
- if (zedManager.IsZEDReady && (cam.nearClipPlane != nearplane || cam.farClipPlane != farplane))
- {
- SetProjection(nearplane, farplane); //If the camera's near/far planes changed, update the matrix.
- }
- #if UNITY_EDITOR
- if (actualRenderingPath != RenderingPath.VertexLit && cam.actualRenderingPath != actualRenderingPath)
- {
- ConfigureLightAndShadow(cam.actualRenderingPath);
- }
- #endif
- }
- /// <summary>
- /// Used by the ZEDMeshRenderer/ZEDPlaneRenderer to draw chunks/planes onto the final images.
- /// </summary>
- private RenderTexture textureMapping;
- /// <summary>
- /// Sets the RenderTexture that gets blended into the final result, if using Plane Detection or Spatial Mapping.
- /// ZEDPlaneRenderer and ZEDMeshRenderer call this with the RenderTextures to which they render each frame.
- /// </summary>
- /// <param name="texture"></param>
- public void SetTextureOverlayMapping(RenderTexture texture)
- {
- textureMapping = texture;
- blender.SetTexture("_ZEDMeshTex", textureMapping);
- }
- public void SetMeshRenderAvailable(bool r)
- {
- int d = -1;
- if (r) d = 0;
- blender.SetInt("_IsTextured", d);
- blender.SetInt(isTexturedID, d);
- }
- #if ZED_HDRP || ZED_URP
- /// <summary>
- /// Blend the wireframe into the image. Used in SRP because there is no OnRenderImage automatic function.
- /// </summary>
- private void SRPStartFrame(ScriptableRenderContext context, Camera[] rendcam)
- {
- foreach(Camera camera in rendcam)
- {
- if (camera == renderingCam && zedManager.GetSpatialMapping.display)
- {
- DrawSpatialMappingMeshes(camera);
- }
- }
- }
- /// <summary>
- /// Draw every chunk of the wiremesh
- /// </summary>
- /// <param name="drawcam"></param>
- private void DrawSpatialMappingMeshes(Camera drawcam)
- {
- ZEDSpatialMapping spatialMapping = zedManager.GetSpatialMapping;
- if (spatialMapping == null) return;
- if(spatialMapping.IsRunning()) // Draw all chunks/submeshes used while spatial mapping is running, before merging.
- {
- foreach (ZEDSpatialMapping.Chunk chunk in spatialMapping.Chunks.Values)
- {
- Matrix4x4 canvastrs = Matrix4x4.TRS(chunk.o.transform.position, chunk.o.transform.rotation, chunk.o.transform.localScale);
- Graphics.DrawMesh(chunk.mesh, canvastrs, chunk.o.GetComponent<MeshRenderer>().material, gameObject.layer, drawcam, 0, null, false, false);
- }
- }
- else if (!spatialMapping.IsRunning()) // Draw final chunks, after merging.
- foreach (ZEDSpatialMapping.Chunk chunk in spatialMapping.ChunkList)
- {
- Matrix4x4 canvastrs = Matrix4x4.TRS(chunk.o.transform.position, chunk.o.transform.rotation, chunk.o.transform.localScale);
- Graphics.DrawMesh(chunk.mesh, canvastrs, chunk.o.GetComponent<MeshRenderer>().material, gameObject.layer, drawcam, 0, null, false, false);
- }
- }
- #else
- /// <summary>
- /// Where the post-processing occurs.
- /// Called by Unity whenever the attached Camera renders an image.
- /// </summary>
- /// <param name="source"></param>
- /// <param name="destination"></param>
- private void OnRenderImage(RenderTexture source, RenderTexture destination)
- {
- if (zedManager.GetSpatialMapping.display) //If displaying a mesh from spatial mapping, blend the wireframe into the image.
- {
- RenderTexture tmpSource = RenderTexture.GetTemporary(source.width, source.height, source.depth, source.format, RenderTextureReadWrite.sRGB);
- Graphics.Blit(source, tmpSource);
- Graphics.Blit(tmpSource, destination, blender);
- RenderTexture.ReleaseTemporary(tmpSource);
- }
- else
- {
- if (ARpostProcessing && mask != null && zedCamera.IsCameraReady) //Apply post-processing, if enabled.
- {
- if (actualRenderingPath == RenderingPath.DeferredShading)
- {
- RenderTexture bluredMask = RenderTexture.GetTemporary(mask.width, mask.height, mask.depth, mask.format);
- RenderTexture buffer = RenderTexture.GetTemporary(source.width, source.height, 24);
- Graphics.SetRenderTarget(buffer);
- GL.Clear(false, true, new Color(0, 0, 0, 0)); // clear the full RT
- //To keep the stencil in post-processing, since Graphics.Blit normally clears it.
- Graphics.SetRenderTarget(buffer.colorBuffer, source.depthBuffer);
- Graphics.Blit(source, matStencilToMask);
- //Compose the second mask retrieved in the forward pass. The shader should set the stencil to 148.
- Graphics.Blit(mask, bluredMask);
- //matComposeMask.SetTexture("_Mask", bluredMask);
- matComposeMask.SetTexture(maskPropID, bluredMask);
- Graphics.Blit(buffer, mask, matComposeMask);
- ApplyPostProcess(source, destination, bluredMask);
- RenderTexture.ReleaseTemporary(buffer);
- RenderTexture.ReleaseTemporary(bluredMask);
- }
- else //Forward path.
- {
- RenderTexture bluredMask = RenderTexture.GetTemporary(mask.width, mask.height, mask.depth, mask.format);
- ApplyPostProcess(source, destination, bluredMask);
- RenderTexture.ReleaseTemporary(bluredMask);
- }
- }
- else //Not using post-processing.
- {
- Graphics.Blit(source, destination);
- }
- }
- }
- #endif
- /// <summary>
- /// Apply post-processing effects to the given RenderTexture.
- /// </summary>
- /// <param name="source">Source RenderTexture.</param>
- /// <param name="destination">Destination RenderTexture.</param>
- /// <param name="bluredMask">Mask used to apply blurring effects.</param>
- private void ApplyPostProcess(RenderTexture source, RenderTexture destination, RenderTexture bluredMask)
- {
- RenderTexture tempDestination = RenderTexture.GetTemporary(source.width, source.height, source.depth, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
- Graphics.Blit(source, tempDestination, postprocessMaterial);
- ZEDPostProcessingTools.Blur(mask, bluredMask, blurMaterial, 3, 1, 1);
- //blurMaterial.SetTexture("_Mask", bluredMask);
- blurMaterial.SetTexture(maskPropID, bluredMask);
- ZEDPostProcessingTools.Blur(tempDestination, destination, blurMaterial, 2, 1, 1);
- mask.SetGlobalShaderProperty("_ZEDMaskVirtual");
- RenderTexture.ReleaseTemporary(tempDestination);
- }
- /// <summary>
- /// Assigns the projection matrix from the ZED to this camera with the specified near/far planes.
- /// </summary><remarks>
- /// Adjusts the matrix values from a copy rather than reassigning them in ZEDCamera to avoid getting applied
- /// to all copies of the camera.
- ///</remarks>
- ///<param name="near">Desired near plane distance.</param>
- ///<param name="far">Desired far plane distance.</param>
- private void SetProjection(float near = 0.1f, float far = 500f)
- {
- //float near = mainCamera.nearClipPlane;
- //float far = mainCamera.farClipPlane;
- Matrix4x4 newmat = zedCamera.Projection;
- newmat[2, 2] = -(far + near) / (far - near);
- newmat[2, 3] = -(2.0f * far * near) / (far - near);
- cam.projectionMatrix = newmat;
- nearplane = near;
- farplane = far;
- }
- /// Forces the ZED's image to be displayed at a 16:9 ratio, regardless of the window's aspect ratio.
- /// This is why the image doesn't stretch when the Game window in the editor is set to Free Aspet.
- /// </summary>
- public class WindowAspectRatio
- {
- /// <summary>
- /// Current screen width.
- /// </summary>
- private int ScreenSizeX = 0;
- /// <summary>
- /// Current screen height.
- /// </summary>
- private int ScreenSizeY = 0;
- /// <summary>
- /// Camera to set to 16:9.
- /// </summary>
- private Camera cam;
- /// <summary>
- /// Aspect ratio targeted.
- /// </summary>
- private const float TARGET_ASPECT = 16.0f / 9.0f;
- public WindowAspectRatio(Camera camera)
- {
- cam = camera;
- RescaleCamera();
- CreateCamera();
- }
- /// <summary>
- /// Create a custom hidden camera to render black bars in the background.
- /// </summary>
- /// <returns></returns>
- private GameObject CreateCamera()
- {
- GameObject o = new GameObject("CameraBlackBackground");
- Camera cam = o.AddComponent<Camera>();
- cam.backgroundColor = Color.black;
- cam.cullingMask = 0;
- cam.clearFlags = CameraClearFlags.SolidColor;
- cam.depth = -int.MaxValue;
- cam.useOcclusionCulling = false;
- #if UNITY_5_6_OR_NEWER
- cam.allowHDR = false;
- cam.allowMSAA = false;
- #endif
- cam.stereoTargetEye = StereoTargetEyeMask.None;
- cam.renderingPath = RenderingPath.Forward;
- o.hideFlags = HideFlags.HideInHierarchy;
- return o;
- }
- /// <summary>
- /// Rescale the view port of the current camera to keep the 16:9 aspect ratio.
- /// This is called on start and updated each frame.
- /// </summary>
- private void RescaleCamera()
- {
- //If no change, then return
- if (Screen.width == ScreenSizeX && Screen.height == ScreenSizeY) return;
- float windowaspect = (float)Screen.width / (float)Screen.height;
- float scaleheight = windowaspect / TARGET_ASPECT;
- if (scaleheight < 1.0f) //Height is too large. Shrink it, adding letterboxes to the top and bottom.
- {
- Rect rect = cam.rect;
- rect.width = 1.0f;
- rect.height = scaleheight;
- rect.x = 0;
- rect.y = (1.0f - scaleheight) / 2.0f;
- //cam.rect = rect;
- }
- else //Height is too small. Reduce width, adding pillarboxes to the sides.
- {
- float scalewidth = 1.0f / scaleheight;
- Rect rect = cam.rect;
- rect.width = scalewidth;
- rect.height = 1.0f;
- rect.x = (1.0f - scalewidth) / 2.0f;
- rect.y = 0;
- cam.rect = rect;
- }
- ScreenSizeX = Screen.width;
- ScreenSizeY = Screen.height;
- }
- /// <summary>
- /// Calls RescaleCamera(). Called in ZEDRenderingPlane's Update() function.
- /// </summary>
- public void Update()
- {
- RescaleCamera();
- }
- }
- }
|