Vrchat writeup (#333)
* first part of the VRChat for gmeets writeup Signed-off-by: Christine Dodrill <me@christine.website> * more words Signed-off-by: Christine Dodrill <me@christine.website> * polishing touches Signed-off-by: Christine Dodrill <me@christine.website>
This commit is contained in:
parent
c6482fe2fc
commit
f8c2897765
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"editor.wordWrap": "wordWrapColumn",
|
||||
"editor.wordWrapColumn": 80,
|
||||
"editor.wordBasedSuggestions": false,
|
||||
"[markdown]":{
|
||||
"editor.wordWrap": "wordWrapColumn",
|
||||
"editor.wordWrapColumn": 80,
|
||||
"vim.textwidth": 80,
|
||||
},
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
---
|
||||
title: "My Convoluted VRChat Google Meet Setup"
|
||||
date: 2021-02-24
|
||||
tags:
|
||||
- oculusquest2
|
||||
- vr
|
||||
- vrchat
|
||||
---
|
||||
|
||||
# My Convoluted VRChat Google Meet Setup
|
||||
|
||||
Recently the place I work for sent us all VR headsets. I decided to see what it
|
||||
would take to use that headset to make my camera show a virtual avatar instead
|
||||
of my meat body face. This is the story of my journey through chaining things
|
||||
together to make work meetings a bit more fun by using a 3D avatar instead of
|
||||
myself in some of them.
|
||||
|
||||
[This post uses SVG for diagrams to help explain what's going on here. You may
|
||||
need to use a browser with SVG support in order to get the best experience with
|
||||
this article. All the diagrams will be explained after the fact so that people
|
||||
using screen readers are not left out.](conversation://Mara/hacker)
|
||||
|
||||
<center>
|
||||
|
||||
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Working at <a href="https://twitter.com/Tailscale?ref_src=twsrc%5Etfw">@Tailscale</a> is great. They sent us all an Oculus Quest 2! <a href="https://t.co/dDhbwO9cFd">pic.twitter.com/dDhbwO9cFd</a></p>— Cadey A. Ratio (@theprincessxena) <a href="https://twitter.com/theprincessxena/status/1362871906597224456?ref_src=twsrc%5Etfw">February 19, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
</center>
|
||||
|
||||
So, let's cover the basics from a high level. At a high level a webcam is just
|
||||
a video source that may or may not have a microphone attached to it. So in
|
||||
order to get my avatar to show up in a video call, I need some way to make some
|
||||
window on my computer act as a webcam. This will make the overall dependency
|
||||
list look like this (for those of you using screen readers I will describe
|
||||
this diagram below):
|
||||
|
||||
<center>
|
||||
|
||||
![](/static/blog/vrchat/simple_graph.svg)
|
||||
|
||||
</center>
|
||||
|
||||
VRChat renders to the Desktop which is picked up by OBS which has the ability
|
||||
to pretend to be a webcam, which is finally picked up by Google Meet.
|
||||
|
||||
If the VR headset that I got from work was a tethered to the PC kind of VR
|
||||
headset like the Valve Index or HTC Vive, the next steps would involve full
|
||||
body tracking or something so that I could have my movements in real life
|
||||
transfer into movements that my avatar makes.
|
||||
|
||||
However, the VR headset we got sent was an Oculus Quest 2. This is a
|
||||
_standalone_ VR headset that is basically an Android tablet that you strap
|
||||
to your face. This makes things a bit more technically challenging because
|
||||
now you need some way to get the video to the headset and the motion tracking
|
||||
data from the headset and to the computer at 90 times per second. This requires
|
||||
a bit more cleverness.
|
||||
|
||||
The Oculus desktop software ships with a feature called Oculus Link that allows
|
||||
you to use a gaming PC to render the VR data to your headset by sending the
|
||||
video streams over USB. I had to dig around for a compatible cable (It needs to
|
||||
be a specific kind of USB-3 to USB-C-3 cable with at least 5 gigabits per
|
||||
second of transfer capacity) since the ones that
|
||||
[Oculus sells](https://www.oculus.com/accessories/oculus-link/) are both at
|
||||
least CAD$110 and out of stock anywhere I can find them in Canada. The 0.75
|
||||
meter long cable I had been using was good enough to get me through the first
|
||||
couple days of experimenting with VR, but it was clear that a better solution
|
||||
was needed.
|
||||
|
||||
I did some digging and found a bit of software called
|
||||
[ALVR](https://github.com/alvr-org/alvr#readme) that claimed to let me do VR
|
||||
from my computer wirelessly. So I set it up on the Quest and on my tower,
|
||||
which brought up the dependency graph to this:
|
||||
|
||||
<center>
|
||||
|
||||
![](/static/blog/vrchat/alvr_graph.svg)
|
||||
|
||||
</center>
|
||||
|
||||
ALVR talks with its counterpart on the Quest. This allows you to stream the VR
|
||||
video and audio bidirectionally. You also need to bring Virtual Audio Cable
|
||||
into the setup so that you can hear stuff in the game and so that other people
|
||||
can hear you using the headset mic. However, ALVR is not available on the Quest
|
||||
store. You need to install [SideQuest](https://sidequestvr.com/setup-howto) for
|
||||
that.
|
||||
|
||||
[SideQuest lets you sideload Android APK files to your Quest 2 because the
|
||||
Quest 2 is basically an Android tablet that you strap to your face!](conversation://Mara/happy)
|
||||
|
||||
So I used SideQuest to install the ALVR client on my Quest 2, and then I opened
|
||||
up VRChat and was able to do everything I was able to do with the wired cable.
|
||||
It worked beautifully until it didn't. I started running into issues with the
|
||||
video stream just dying. The foveated encoding (tl;dr: attempting to hack the
|
||||
image quality based on how eyes work so you don't notice the artifacting as
|
||||
much) could only do so much and it just ended up not working. Even when I was
|
||||
only doing it for short amounts of time. There is a lot of WiFi noise in my
|
||||
apartment or something and it was really interfering with ALVR's stream
|
||||
encoding. The latency was also noticeable after a bit.
|
||||
|
||||
However, when it worked it worked beautifully. I had to upgrade to the nightly
|
||||
build of ALVR in order to get game audio and the headset mic working, but once
|
||||
it all worked it was really convenient. I could walk around my apartment and
|
||||
I'd also walk around in-game.
|
||||
|
||||
A friend told me that the best experience I could have with wireless VR using a
|
||||
Quest 2 would be to use [Virtual Desktop](https://www.vrdesktop.net). Apparently
|
||||
Virtual Desktop has a
|
||||
[patch that enables SteamVR support](https://sidequestvr.com/app/16), so I
|
||||
purchased Virtual Desktop on a whim and decided to give it a go.
|
||||
|
||||
Virtual Desktop made ALVR look like a tech demo. All of the latency issues were
|
||||
solved instantly. Virtual Desktop also made it convenient for me to access my
|
||||
tower's monitors while in VR, and it has the best typing experience in VR that
|
||||
I've ever used.
|
||||
|
||||
This brings the dependency graph up to this:
|
||||
|
||||
<center>
|
||||
|
||||
![](/static/blog/vrchat/total_graph.svg)
|
||||
|
||||
</center>
|
||||
|
||||
Now all that was left was to make the camera view look somewhat like it does
|
||||
when I'm using my work laptop's webcam to make video calls. I started out by taking a picture of my office from about the angle that my laptop sits at.
|
||||
I ended up with this image:
|
||||
|
||||
<center>
|
||||
|
||||
![](https://cdn.christine.website/file/christine-static/blog/2021-02-24-20-20-58.jpg)
|
||||
|
||||
</center>
|
||||
|
||||
Then with some clever use of the
|
||||
[Chroma key filter in VRChat](https://docs.vrchat.com/docs/vrchat-201812)
|
||||
I was able to get some basic compositing of my avatar onto the picture. I
|
||||
fiddled with the placement of things and then I was able to declare success
|
||||
with this image I posted to Twitter:
|
||||
|
||||
<center>
|
||||
|
||||
![](https://cdn.christine.website/file/christine-static/blog/Eu6iR6jXUAQH0iq.jpeg)
|
||||
|
||||
</center>
|
||||
|
||||
And it worked! I was able to make a call in Google Meet to myself and my
|
||||
avatar's lip movements synchronized somewhat with the words I was saying. I
|
||||
had waifu mode enabled!
|
||||
|
||||
[The avatar being used there is based on a character from Xenoblade Chronicles
|
||||
2 named Pneuma.](conversation://Mara/hacker)
|
||||
|
||||
However, this setup was really janky. I didn't actually get the proper angle
|
||||
for what my work laptop's camera would actually see. Everything was offset to
|
||||
the side and it was at way the wrong angle in general. I'm also not sure if I
|
||||
messed up the sizing of the background image in the OBS view, it looks kinda
|
||||
stretched on my end as I'm writing this post.
|
||||
|
||||
So I decided that the best way to get the most accurate angle was to record a
|
||||
video loop using my work laptop's webcam. After some googling I found
|
||||
[webcamera.io](https://webcamera.io) which let me record some footage of my
|
||||
office from my work laptop's camera angle. I got down under the desk (so I was
|
||||
out of view of the camera) and then recorded a 45 second loop of my office
|
||||
doing nothing (however the flag was slightly moving in the breeze from the desk
|
||||
fan).
|
||||
|
||||
I also found a VRChat world that claimed to be as optimized as you could
|
||||
possibly make a VRChat world. It was a blue cube about 30m by 30m. Checking
|
||||
with SteamVR it brought my frame times down to 3 milliseconds with the stream
|
||||
camera set up for OBS. It looks like this:
|
||||
|
||||
<center>
|
||||
|
||||
![Screenshot of the optimized world](https://cdn.christine.website/file/christine-static/blog/154306141_1368071216896631_2989259612329820447_o.jpg)
|
||||
|
||||
</center>
|
||||
|
||||
It's very minimal. You can make the walls go away if you want, which somehow makes it render faster on my RX5700. I'm not sure what's going on there.
|
||||
|
||||
[I'd heckin' love to get a new GPU but until the Bitcoin prices go down we may
|
||||
be stuck with this setup for a while. An RTX 3070 would really be useful about
|
||||
now.](conversation://Mara/hacker)
|
||||
|
||||
Anyways, with this minimal world incurring very little to no GPU load, I was
|
||||
free to do video calls all I wanted. I even did a call with the CEO of the
|
||||
company I work for with a setup like this. It was fun.
|
||||
|
||||
Now I had everything set up. I can pop on the headset, load up the world, open
|
||||
OBS, VRChat, Virtual Desktop and get everything set up in about 5 minutes at
|
||||
worst. Then I can use the seeing your desktop side of Virtual Desktop to
|
||||
actually watch the meeting and be able to see screen sharing. They can hear me
|
||||
because Virtual Desktop pipes the headset microphone audio back to my tower,
|
||||
and the meeting audio comes over my headphones.
|
||||
|
||||
Also at some point I needed to bring AutoHotKey into the mix, so I borrowed
|
||||
this AutoHotKey script from [SuperUser](https://superuser.com/a/429845) to
|
||||
resize the VRChat window so that it would fit perfectly into the OBS view:
|
||||
|
||||
```ahk
|
||||
#=:: ; [Win]+[=]
|
||||
WinGet, window, ID, A
|
||||
InputBox, width, Resize, Width:, , 140, 130
|
||||
InputBox, height, Resize, Height:, , 140, 130
|
||||
WinMove, ahk_id %window%, , , , width, height
|
||||
return
|
||||
```
|
||||
|
||||
Making the VRChat window smaller also helped with the frame times, because it
|
||||
needed to render less detail per frame. This helped push the framerate
|
||||
comfortably above 72 FPS in my VR view.
|
||||
|
||||
That is how I get a 3d avatar to show up instead of pictures of the meat golem
|
||||
I am cursed inside of for work meetings. I will also use this for streaming
|
||||
coding in the future, so you can all witness the power of a VTube coding stream
|
||||
where I write Rust or something.
|
|
@ -0,0 +1,172 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: G Pages: 1 -->
|
||||
<svg width="661pt" height="308pt"
|
||||
viewBox="0.00 0.00 661.01 308.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 304)">
|
||||
<title>G</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-304 657.0118,-304 657.0118,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_0</title>
|
||||
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="150.8243,-8 150.8243,-107 374.9943,-107 374.9943,-8 150.8243,-8"/>
|
||||
<text text-anchor="middle" x="262.9093" y="-90.4" font-family="Times,serif" font-size="14.00" fill="#000000">Quest</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_1</title>
|
||||
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="8,-115 8,-292 645.0118,-292 645.0118,-115 8,-115"/>
|
||||
<text text-anchor="middle" x="326.5059" y="-275.4" font-family="Times,serif" font-size="14.00" fill="#000000">PC</text>
|
||||
</g>
|
||||
<!-- AVA -->
|
||||
<g id="node1" class="node">
|
||||
<title>AVA</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="328.7382" cy="-45" rx="38.0139" ry="29.3315"/>
|
||||
<text text-anchor="middle" x="328.7382" y="-49.2" font-family="Times,serif" font-size="14.00" fill="#000000">ALVR</text>
|
||||
<text text-anchor="middle" x="328.7382" y="-32.4" font-family="Times,serif" font-size="14.00" fill="#000000">Quest</text>
|
||||
</g>
|
||||
<!-- AVR -->
|
||||
<g id="node3" class="node">
|
||||
<title>AVR</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="328.7382" cy="-164" rx="42.2164" ry="29.3315"/>
|
||||
<text text-anchor="middle" x="328.7382" y="-168.2" font-family="Times,serif" font-size="14.00" fill="#000000">ALVR</text>
|
||||
<text text-anchor="middle" x="328.7382" y="-151.4" font-family="Times,serif" font-size="14.00" fill="#000000">desktop</text>
|
||||
</g>
|
||||
<!-- AVA->AVR -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>AVA->AVR</title>
|
||||
<path fill="none" stroke="#000000" d="M328.7382,-74.75C328.7382,-91.2066 328.7382,-107.6631 328.7382,-124.1197"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="325.2383,-124.3662 328.7382,-134.3662 332.2383,-124.3662 325.2383,-124.3662"/>
|
||||
</g>
|
||||
<!-- A -->
|
||||
<g id="node2" class="node">
|
||||
<title>A</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="202.0445" cy="-50" rx="43.4415" ry="18"/>
|
||||
<text text-anchor="middle" x="202.0445" y="-45.8" font-family="Times,serif" font-size="14.00" fill="#000000">Android</text>
|
||||
</g>
|
||||
<!-- A->AVA -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>A->AVA</title>
|
||||
<path fill="none" stroke="#000000" d="M245.2909,-48.2933C256.4871,-47.8514 268.6178,-47.3727 280.071,-46.9207"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="280.4983,-50.4066 290.3525,-46.5149 280.2222,-43.4121 280.4983,-50.4066"/>
|
||||
</g>
|
||||
<!-- AVR->AVA -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>AVR->AVA</title>
|
||||
<path fill="none" stroke="#000000" d="M328.7382,-134.3662C328.7382,-117.9097 328.7382,-101.4531 328.7382,-84.9965"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="332.2383,-84.75 328.7382,-74.75 325.2383,-84.75 332.2383,-84.75"/>
|
||||
</g>
|
||||
<!-- VAC -->
|
||||
<g id="node11" class="node">
|
||||
<title>VAC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="463.4742" cy="-164" rx="39.2066" ry="41.0911"/>
|
||||
<text text-anchor="middle" x="463.4742" y="-176.6" font-family="Times,serif" font-size="14.00" fill="#000000">Virtual</text>
|
||||
<text text-anchor="middle" x="463.4742" y="-159.8" font-family="Times,serif" font-size="14.00" fill="#000000">Audio</text>
|
||||
<text text-anchor="middle" x="463.4742" y="-143" font-family="Times,serif" font-size="14.00" fill="#000000">Cable</text>
|
||||
</g>
|
||||
<!-- AVR->VAC -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>AVR->VAC</title>
|
||||
<path fill="none" stroke="#000000" d="M370.9998,-164C384.6622,-164 399.9322,-164 414.0648,-164"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="414.1153,-167.5001 424.1152,-164 414.1152,-160.5001 414.1153,-167.5001"/>
|
||||
</g>
|
||||
<!-- SVR -->
|
||||
<g id="node4" class="node">
|
||||
<title>SVR</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="202.0445" cy="-170" rx="48.6714" ry="18"/>
|
||||
<text text-anchor="middle" x="202.0445" y="-165.8" font-family="Times,serif" font-size="14.00" fill="#000000">SteamVR</text>
|
||||
</g>
|
||||
<!-- SVR->AVR -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>SVR->AVR</title>
|
||||
<path fill="none" stroke="#000000" d="M250.3034,-167.7145C258.7549,-167.3143 267.5869,-166.896 276.1488,-166.4905"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="276.5916,-169.9736 286.4148,-166.0044 276.2604,-162.9814 276.5916,-169.9736"/>
|
||||
</g>
|
||||
<!-- VRC -->
|
||||
<g id="node5" class="node">
|
||||
<title>VRC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="66.7294" cy="-206" rx="42.8751" ry="18"/>
|
||||
<text text-anchor="middle" x="66.7294" y="-201.8" font-family="Times,serif" font-size="14.00" fill="#000000">VRChat</text>
|
||||
</g>
|
||||
<!-- VRC->SVR -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>VRC->SVR</title>
|
||||
<path fill="none" stroke="#000000" d="M102.9914,-196.3527C118.1616,-192.3167 136.0376,-187.5609 152.3981,-183.2082"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="153.5873,-186.5137 162.3513,-180.5602 151.7875,-179.749 153.5873,-186.5137"/>
|
||||
</g>
|
||||
<!-- DESK -->
|
||||
<g id="node10" class="node">
|
||||
<title>DESK</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="202.0445" cy="-229" rx="43.4396" ry="18"/>
|
||||
<text text-anchor="middle" x="202.0445" y="-224.8" font-family="Times,serif" font-size="14.00" fill="#000000">Desktop</text>
|
||||
</g>
|
||||
<!-- VRC->DESK -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>VRC->DESK</title>
|
||||
<path fill="none" stroke="#000000" d="M106.5966,-212.7764C120.7849,-215.188 136.9469,-217.9351 151.8865,-220.4745"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="151.5496,-223.9673 161.9947,-222.1926 152.7227,-217.0663 151.5496,-223.9673"/>
|
||||
</g>
|
||||
<!-- OBS -->
|
||||
<g id="node6" class="node">
|
||||
<title>OBS</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="328.7382" cy="-235" rx="29.6339" ry="18"/>
|
||||
<text text-anchor="middle" x="328.7382" y="-230.8" font-family="Times,serif" font-size="14.00" fill="#000000">OBS</text>
|
||||
</g>
|
||||
<!-- VIRC -->
|
||||
<g id="node7" class="node">
|
||||
<title>VIRC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="463.4742" cy="-241" rx="56.7561" ry="18"/>
|
||||
<text text-anchor="middle" x="463.4742" y="-236.8" font-family="Times,serif" font-size="14.00" fill="#000000">VirtualCam</text>
|
||||
</g>
|
||||
<!-- OBS->VIRC -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>OBS->VIRC</title>
|
||||
<path fill="none" stroke="#000000" d="M358.6405,-236.3316C370.0698,-236.8406 383.6086,-237.4435 397.0947,-238.044"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="397.2155,-241.5528 407.3614,-238.5012 397.527,-234.5597 397.2155,-241.5528"/>
|
||||
</g>
|
||||
<!-- GM -->
|
||||
<g id="node8" class="node">
|
||||
<title>GM</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="596.5569" cy="-197" rx="40.4098" ry="29.3315"/>
|
||||
<text text-anchor="middle" x="596.5569" y="-201.2" font-family="Times,serif" font-size="14.00" fill="#000000">Google</text>
|
||||
<text text-anchor="middle" x="596.5569" y="-184.4" font-family="Times,serif" font-size="14.00" fill="#000000">Meet</text>
|
||||
</g>
|
||||
<!-- VIRC->GM -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>VIRC->GM</title>
|
||||
<path fill="none" stroke="#000000" d="M503.043,-227.9177C517.7504,-223.0551 534.5739,-217.4929 549.8596,-212.4391"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="551.2489,-215.6662 559.6447,-209.204 549.0515,-209.02 551.2489,-215.6662"/>
|
||||
</g>
|
||||
<!-- SQ -->
|
||||
<g id="node9" class="node">
|
||||
<title>SQ</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="66.7294" cy="-141" rx="50.9599" ry="18"/>
|
||||
<text text-anchor="middle" x="66.7294" y="-136.8" font-family="Times,serif" font-size="14.00" fill="#000000">SideQuest</text>
|
||||
</g>
|
||||
<!-- SQ->AVA -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>SQ->AVA</title>
|
||||
<path fill="none" stroke="#000000" d="M103.9261,-128.7112C141.2245,-116.2351 200.2025,-96.0887 250.6301,-77 262.0869,-72.6632 274.3899,-67.7466 285.765,-63.0913"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="287.15,-66.3061 295.0628,-59.2607 284.4835,-59.8339 287.15,-66.3061"/>
|
||||
</g>
|
||||
<!-- SQ->A -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>SQ->A</title>
|
||||
<path fill="none" stroke="#000000" d="M90.6096,-124.9405C112.7736,-110.0351 145.9219,-87.7427 170.305,-71.3449"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="172.5102,-74.0798 178.8551,-65.595 168.6038,-68.2712 172.5102,-74.0798"/>
|
||||
</g>
|
||||
<!-- DESK->OBS -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>DESK->OBS</title>
|
||||
<path fill="none" stroke="#000000" d="M245.2909,-231.0481C259.3432,-231.7136 274.8677,-232.4488 288.6771,-233.1028"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="288.6958,-236.6075 298.8502,-233.5846 289.027,-229.6153 288.6958,-236.6075"/>
|
||||
</g>
|
||||
<!-- VAC->GM -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>VAC->GM</title>
|
||||
<path fill="none" stroke="#000000" d="M501.9672,-173.545C516.4509,-177.1364 533.1046,-181.266 548.3623,-185.0494"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="547.6019,-188.4668 558.1504,-187.4765 549.2867,-181.6725 547.6019,-188.4668"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.0 KiB |
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: G Pages: 1 -->
|
||||
<svg width="610pt" height="123pt"
|
||||
viewBox="0.00 0.00 609.61 123.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 119)">
|
||||
<title>G</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-119 605.611,-119 605.611,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_1</title>
|
||||
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="8,-8 8,-107 593.611,-107 593.611,-8 8,-8"/>
|
||||
<text text-anchor="middle" x="300.8055" y="-90.4" font-family="Times,serif" font-size="14.00" fill="#000000">PC</text>
|
||||
</g>
|
||||
<!-- VRC -->
|
||||
<g id="node1" class="node">
|
||||
<title>VRC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="58.6871" cy="-45" rx="42.8751" ry="18"/>
|
||||
<text text-anchor="middle" x="58.6871" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">VRChat</text>
|
||||
</g>
|
||||
<!-- DESK -->
|
||||
<g id="node5" class="node">
|
||||
<title>DESK</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="180.5935" cy="-45" rx="43.4396" ry="18"/>
|
||||
<text text-anchor="middle" x="180.5935" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">Desktop</text>
|
||||
</g>
|
||||
<!-- VRC->DESK -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>VRC->DESK</title>
|
||||
<path fill="none" stroke="#000000" d="M101.6668,-45C109.8542,-45 118.5168,-45 126.9873,-45"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="127.1794,-48.5001 137.1794,-45 127.1793,-41.5001 127.1794,-48.5001"/>
|
||||
</g>
|
||||
<!-- OBS -->
|
||||
<g id="node2" class="node">
|
||||
<title>OBS</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="289.6291" cy="-45" rx="29.6339" ry="18"/>
|
||||
<text text-anchor="middle" x="289.6291" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">OBS</text>
|
||||
</g>
|
||||
<!-- VIRC -->
|
||||
<g id="node3" class="node">
|
||||
<title>VIRC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="412.0734" cy="-45" rx="56.7561" ry="18"/>
|
||||
<text text-anchor="middle" x="412.0734" y="-40.8" font-family="Times,serif" font-size="14.00" fill="#000000">VirtualCam</text>
|
||||
</g>
|
||||
<!-- OBS->VIRC -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>OBS->VIRC</title>
|
||||
<path fill="none" stroke="#000000" d="M319.5824,-45C327.4013,-45 336.1504,-45 345.0646,-45"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="345.1584,-48.5001 355.1584,-45 345.1584,-41.5001 345.1584,-48.5001"/>
|
||||
</g>
|
||||
<!-- GM -->
|
||||
<g id="node4" class="node">
|
||||
<title>GM</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="545.1562" cy="-45" rx="40.4098" ry="29.3315"/>
|
||||
<text text-anchor="middle" x="545.1562" y="-49.2" font-family="Times,serif" font-size="14.00" fill="#000000">Google</text>
|
||||
<text text-anchor="middle" x="545.1562" y="-32.4" font-family="Times,serif" font-size="14.00" fill="#000000">Meet</text>
|
||||
</g>
|
||||
<!-- VIRC->GM -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>VIRC->GM</title>
|
||||
<path fill="none" stroke="#000000" d="M468.8985,-45C477.4369,-45 486.1935,-45 494.5894,-45"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="494.6128,-48.5001 504.6128,-45 494.6128,-41.5001 494.6128,-48.5001"/>
|
||||
</g>
|
||||
<!-- DESK->OBS -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>DESK->OBS</title>
|
||||
<path fill="none" stroke="#000000" d="M224.0006,-45C232.4355,-45 241.241,-45 249.5623,-45"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="249.7795,-48.5001 259.7795,-45 249.7795,-41.5001 249.7795,-48.5001"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: G Pages: 1 -->
|
||||
<svg width="671pt" height="332pt"
|
||||
viewBox="0.00 0.00 670.88 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
|
||||
<title>G</title>
|
||||
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-328 666.8816,-328 666.8816,4 -4,4"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_0</title>
|
||||
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="150.8243,-8 150.8243,-131 525.6487,-131 525.6487,-8 150.8243,-8"/>
|
||||
<text text-anchor="middle" x="338.2365" y="-114.4" font-family="Times,serif" font-size="14.00" fill="#000000">Quest</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_1</title>
|
||||
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="8,-139 8,-316 654.8816,-316 654.8816,-139 8,-139"/>
|
||||
<text text-anchor="middle" x="331.4408" y="-299.4" font-family="Times,serif" font-size="14.00" fill="#000000">PC</text>
|
||||
</g>
|
||||
<!-- VD -->
|
||||
<g id="node1" class="node">
|
||||
<title>VD</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="473.3439" cy="-63" rx="44.1104" ry="29.3315"/>
|
||||
<text text-anchor="middle" x="473.3439" y="-67.2" font-family="Times,serif" font-size="14.00" fill="#000000">Virtual</text>
|
||||
<text text-anchor="middle" x="473.3439" y="-50.4" font-family="Times,serif" font-size="14.00" fill="#000000">Desktop</text>
|
||||
</g>
|
||||
<!-- VDS -->
|
||||
<g id="node4" class="node">
|
||||
<title>VDS</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="333.6731" cy="-188" rx="47.086" ry="41.0911"/>
|
||||
<text text-anchor="middle" x="333.6731" y="-200.6" font-family="Times,serif" font-size="14.00" fill="#000000">Virtual</text>
|
||||
<text text-anchor="middle" x="333.6731" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">Desktop</text>
|
||||
<text text-anchor="middle" x="333.6731" y="-167" font-family="Times,serif" font-size="14.00" fill="#000000">Streamer</text>
|
||||
</g>
|
||||
<!-- VD->VDS -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>VD->VDS</title>
|
||||
<path fill="none" stroke="#000000" d="M450.736,-88.362C431.0544,-107.6122 401.9557,-134.0523 377.6943,-154.9249"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="375.3377,-152.3348 370.0053,-161.4899 379.8831,-157.6583 375.3377,-152.3348"/>
|
||||
</g>
|
||||
<!-- VDM -->
|
||||
<g id="node2" class="node">
|
||||
<title>VDM</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="333.6731" cy="-57" rx="45.275" ry="41.0911"/>
|
||||
<text text-anchor="middle" x="333.6731" y="-69.6" font-family="Times,serif" font-size="14.00" fill="#000000">Virtual</text>
|
||||
<text text-anchor="middle" x="333.6731" y="-52.8" font-family="Times,serif" font-size="14.00" fill="#000000">Desktop</text>
|
||||
<text text-anchor="middle" x="333.6731" y="-36" font-family="Times,serif" font-size="14.00" fill="#000000">VR mod</text>
|
||||
</g>
|
||||
<!-- VDM->VD -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>VDM->VD</title>
|
||||
<path fill="none" stroke="#000000" d="M379.0202,-58.948C391.5906,-59.488 405.3731,-60.0801 418.4262,-60.6408"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="418.5601,-64.1497 428.7011,-61.0822 418.8606,-57.1562 418.5601,-64.1497"/>
|
||||
</g>
|
||||
<!-- A -->
|
||||
<g id="node3" class="node">
|
||||
<title>A</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="202.0445" cy="-68" rx="43.4415" ry="18"/>
|
||||
<text text-anchor="middle" x="202.0445" y="-63.8" font-family="Times,serif" font-size="14.00" fill="#000000">Android</text>
|
||||
</g>
|
||||
<!-- A->VDM -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>A->VDM</title>
|
||||
<path fill="none" stroke="#000000" d="M244.7805,-64.4286C255.4706,-63.5353 267.0909,-62.5642 278.2968,-61.6277"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="278.7592,-65.1014 288.433,-60.7806 278.1762,-58.1257 278.7592,-65.1014"/>
|
||||
</g>
|
||||
<!-- VDS->VD -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>VDS->VD</title>
|
||||
<path fill="none" stroke="#000000" d="M363.2937,-155.8547C384.2099,-135.824 412.4271,-110.4172 435.0521,-91.1733"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="437.4099,-93.7634 442.8005,-84.6424 432.8986,-88.411 437.4099,-93.7634"/>
|
||||
</g>
|
||||
<!-- GM -->
|
||||
<g id="node9" class="node">
|
||||
<title>GM</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="606.4267" cy="-216" rx="40.4098" ry="29.3315"/>
|
||||
<text text-anchor="middle" x="606.4267" y="-220.2" font-family="Times,serif" font-size="14.00" fill="#000000">Google</text>
|
||||
<text text-anchor="middle" x="606.4267" y="-203.4" font-family="Times,serif" font-size="14.00" fill="#000000">Meet</text>
|
||||
</g>
|
||||
<!-- VDS->GM -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>VDS->GM</title>
|
||||
<path fill="none" stroke="#000000" d="M380.5611,-192.8134C429.5797,-197.8455 506.2147,-205.7126 556.3811,-210.8625"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="556.0498,-214.3468 566.355,-211.8864 556.7647,-207.3834 556.0498,-214.3468"/>
|
||||
</g>
|
||||
<!-- SVR -->
|
||||
<g id="node5" class="node">
|
||||
<title>SVR</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="202.0445" cy="-188" rx="48.6714" ry="18"/>
|
||||
<text text-anchor="middle" x="202.0445" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">SteamVR</text>
|
||||
</g>
|
||||
<!-- SVR->VDS -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>SVR->VDS</title>
|
||||
<path fill="none" stroke="#000000" d="M250.6841,-188C259.0146,-188 267.7397,-188 276.273,-188"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="276.5472,-191.5001 286.5471,-188 276.5471,-184.5001 276.5472,-191.5001"/>
|
||||
</g>
|
||||
<!-- VRC -->
|
||||
<g id="node6" class="node">
|
||||
<title>VRC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="66.7294" cy="-230" rx="42.8751" ry="18"/>
|
||||
<text text-anchor="middle" x="66.7294" y="-225.8" font-family="Times,serif" font-size="14.00" fill="#000000">VRChat</text>
|
||||
</g>
|
||||
<!-- VRC->SVR -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>VRC->SVR</title>
|
||||
<path fill="none" stroke="#000000" d="M101.2253,-219.293C117.6099,-214.2074 137.4417,-208.0518 155.1663,-202.5504"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="156.2483,-205.8793 164.7613,-199.5722 154.1732,-199.194 156.2483,-205.8793"/>
|
||||
</g>
|
||||
<!-- DESK -->
|
||||
<g id="node11" class="node">
|
||||
<title>DESK</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="202.0445" cy="-242" rx="43.4396" ry="18"/>
|
||||
<text text-anchor="middle" x="202.0445" y="-237.8" font-family="Times,serif" font-size="14.00" fill="#000000">Desktop</text>
|
||||
</g>
|
||||
<!-- VRC->DESK -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>VRC->DESK</title>
|
||||
<path fill="none" stroke="#000000" d="M108.8022,-233.7311C121.6615,-234.8715 135.9668,-236.1401 149.4342,-237.3344"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="149.2616,-240.8328 159.5317,-238.2299 149.88,-233.8601 149.2616,-240.8328"/>
|
||||
</g>
|
||||
<!-- OBS -->
|
||||
<g id="node7" class="node">
|
||||
<title>OBS</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="333.6731" cy="-265" rx="29.6339" ry="18"/>
|
||||
<text text-anchor="middle" x="333.6731" y="-260.8" font-family="Times,serif" font-size="14.00" fill="#000000">OBS</text>
|
||||
</g>
|
||||
<!-- VIRC -->
|
||||
<g id="node8" class="node">
|
||||
<title>VIRC</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="473.3439" cy="-255" rx="56.7561" ry="18"/>
|
||||
<text text-anchor="middle" x="473.3439" y="-250.8" font-family="Times,serif" font-size="14.00" fill="#000000">VirtualCam</text>
|
||||
</g>
|
||||
<!-- OBS->VIRC -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>OBS->VIRC</title>
|
||||
<path fill="none" stroke="#000000" d="M363.2937,-262.8793C376.2998,-261.9481 392.129,-260.8147 407.6812,-259.7012"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="408.1043,-263.18 417.8288,-258.9747 407.6044,-256.1979 408.1043,-263.18"/>
|
||||
</g>
|
||||
<!-- VIRC->GM -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>VIRC->GM</title>
|
||||
<path fill="none" stroke="#000000" d="M515.087,-242.7672C529.0844,-238.6652 544.7902,-234.0626 559.1786,-229.8461"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="560.28,-233.1706 568.8921,-226.9995 558.3114,-226.4531 560.28,-233.1706"/>
|
||||
</g>
|
||||
<!-- SQ -->
|
||||
<g id="node10" class="node">
|
||||
<title>SQ</title>
|
||||
<ellipse fill="#ffffff" stroke="#ffffff" cx="66.7294" cy="-165" rx="50.9599" ry="18"/>
|
||||
<text text-anchor="middle" x="66.7294" y="-160.8" font-family="Times,serif" font-size="14.00" fill="#000000">SideQuest</text>
|
||||
</g>
|
||||
<!-- SQ->A -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>SQ->A</title>
|
||||
<path fill="none" stroke="#000000" d="M89.3781,-148.7644C111.9913,-132.5542 146.8811,-107.5436 171.8411,-89.6512"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="174.1309,-92.3162 180.2192,-83.6453 170.0526,-86.6269 174.1309,-92.3162"/>
|
||||
</g>
|
||||
<!-- DESK->VDS -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>DESK->VDS</title>
|
||||
<path fill="none" stroke="#000000" d="M232.9056,-229.3394C247.3882,-223.3979 265.0521,-216.1514 281.5218,-209.3948"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="283.1245,-212.5204 291.0478,-205.4868 280.4677,-206.0442 283.1245,-212.5204"/>
|
||||
</g>
|
||||
<!-- DESK->OBS -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>DESK->OBS</title>
|
||||
<path fill="none" stroke="#000000" d="M242.2526,-249.0257C259.0321,-251.9577 278.4424,-255.3493 295.05,-258.2512"/>
|
||||
<polygon fill="#000000" stroke="#000000" points="294.5265,-261.7127 304.9797,-259.9863 295.7315,-254.8172 294.5265,-261.7127"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.0 KiB |
Loading…
Reference in New Issue