public void CreateMirror(Vector3 position, Quaternion rotation, Vector2 size, Transform container, Vector3?origin = null) { if (!_shaderLoader.stereoMirrorShader) { _logger.Error("Stereo Mirror shader not loaded; mirror will not be created"); return; } Vector3 scale = new Vector3(size.x / 10, 1, size.y / 10); // plane is 10 units in size at scale 1, width is x and height is z GameObject mirrorPlane = GameObject.CreatePrimitive(PrimitiveType.Plane); mirrorPlane.transform.SetParent(container); mirrorPlane.name = "Stereo Mirror"; mirrorPlane.transform.localScale = scale; mirrorPlane.transform.localPosition = position; mirrorPlane.transform.localRotation = rotation; Material material = new Material(_shaderLoader.stereoMirrorShader); material.SetFloat(kCutout, 0f); Renderer renderer = mirrorPlane.GetComponent <Renderer>(); renderer.sharedMaterial = material; GameObject stereoCameraHead = new GameObject($"Stereo Camera Head [{mirrorPlane.name}]"); stereoCameraHead.transform.SetParent(mirrorPlane.transform, false); stereoCameraHead.transform.localScale = new Vector3(1 / scale.x, 1 / scale.y, 1 / scale.z); GameObject stereoCameraEyeObject = new GameObject($"Stereo Camera Eye [{mirrorPlane.name}]"); stereoCameraEyeObject.transform.SetParent(mirrorPlane.transform, false); Camera stereoCameraEye = stereoCameraEyeObject.AddComponent <Camera>(); stereoCameraEye.enabled = false; stereoCameraEye.cullingMask = AvatarLayers.kAllLayersMask; stereoCameraEye.clearFlags = CameraClearFlags.SolidColor; // kind of hacky but setting the color to pure black or white causes the camera to // to give nothing to the render texture when there are no objects to render, // resulting in a black rectangle instead of a transparent mirror stereoCameraEye.backgroundColor = new Color(0, 1, 0, 1f); StereoRenderer stereoRenderer = _container.InstantiateComponent <StereoRenderer>(mirrorPlane); stereoRenderer.stereoCameraHead = stereoCameraHead; stereoRenderer.stereoCameraEye = stereoCameraEye; stereoRenderer.isMirror = true; stereoRenderer.useScissor = false; stereoRenderer.canvasOriginPos = origin ?? mirrorPlane.transform.position; stereoRenderer.canvasOriginRot = mirrorPlane.transform.rotation; stereoRenderer.renderScale = _settings.mirror.renderScale; }
///////////////////////////////////////////////////////////////////////////////// // render related public void InvokeStereoRenderers(VRRenderEventDetector detector) { // render registored stereo cameras for (int renderIter = 0; renderIter < stereoRenderers.Count; renderIter++) { StereoRenderer stereoRenderer = stereoRenderers[renderIter]; if (stereoRenderer.shouldRender) { stereoRenderer.Render(detector); } } }
public static IEnumerator <AsyncOperation> SpawnMirror(Vector3 position, Quaternion rotation, Vector3 scale, Transform container) { AssetBundleCreateRequest shadersBundleCreateRequest = AssetBundle.LoadFromFileAsync("CustomAvatars/Shaders/customavatars.assetbundle"); yield return(shadersBundleCreateRequest); if (!shadersBundleCreateRequest.isDone || shadersBundleCreateRequest.assetBundle == null) { Plugin.logger.Error("Failed to load stereo mirror shader"); yield break; } AssetBundleRequest assetBundleRequest = shadersBundleCreateRequest.assetBundle.LoadAssetAsync <Shader>("Assets/Shaders/StereoRenderShader-Unlit.shader"); yield return(assetBundleRequest); shadersBundleCreateRequest.assetBundle.Unload(false); if (!assetBundleRequest.isDone || assetBundleRequest.asset == null) { Plugin.logger.Error("Failed to load stereo mirror shader"); yield break; } Shader stereoRenderShader = assetBundleRequest.asset as Shader; GameObject mirrorPlane = GameObject.CreatePrimitive(PrimitiveType.Plane); mirrorPlane.transform.SetParent(container); mirrorPlane.name = "Stereo Mirror"; mirrorPlane.transform.localScale = scale; mirrorPlane.transform.localPosition = position + new Vector3(0, scale.z * 5, 0); // plane is 10 units in size at scale 1 mirrorPlane.transform.localRotation = rotation; Material material = new Material(stereoRenderShader); material.SetFloat("_Cutout", 0.01f); Renderer renderer = mirrorPlane.GetComponent <Renderer>(); renderer.sharedMaterial = material; GameObject stereoCameraHead = new GameObject("Stereo Camera Head [Stereo Mirror]"); stereoCameraHead.transform.SetParent(mirrorPlane.transform, false); stereoCameraHead.transform.localScale = new Vector3(1 / scale.x, 1 / scale.y, 1 / scale.z); GameObject stereoCameraEyeObject = new GameObject("Stereo Camera Eye [Stereo Mirror]"); stereoCameraEyeObject.transform.SetParent(mirrorPlane.transform, false); Camera stereoCameraEye = stereoCameraEyeObject.AddComponent <Camera>(); stereoCameraEye.enabled = false; stereoCameraEye.cullingMask = (1 << AvatarLayers.AlwaysVisible) | (1 << AvatarLayers.OnlyInThirdPerson); stereoCameraEye.clearFlags = CameraClearFlags.SolidColor; stereoCameraEye.backgroundColor = new Color(0, 0, 0, 1f); StereoRenderer stereoRenderer = mirrorPlane.AddComponent <StereoRenderer>(); stereoRenderer.stereoCameraHead = stereoCameraHead; stereoRenderer.stereoCameraEye = stereoCameraEye; stereoRenderer.isMirror = true; stereoRenderer.useScissor = false; stereoRenderer.canvasOriginPos = mirrorPlane.transform.position + new Vector3(-10f, 0, 0); stereoRenderer.canvasOriginRot = mirrorPlane.transform.rotation; }
public void RemoveFromManager(StereoRenderer stereoRenderer) { stereoRenderers.Remove(stereoRenderer); }
///////////////////////////////////////////////////////////////////////////////// // callbacks public void AddToManager(StereoRenderer stereoRenderer) { stereoRenderers.Add(stereoRenderer); }