iphone rift with Virieo, Intugame, Gagagu, and Zeiss VR One
Posted: Thu May 07, 2015 8:11 pm
I have recently been bitten by the VR bug and I have to share some things that I have learned. This started with my fascination with Google Cardboard. I immediately started hunting in the app store for vr apps and I ran across Gagagu Streamer to stream games from by pc to my iphone. It was hard to configure and didn't do much except put a non 3D sbs image on my iphone 6. Before too long I discovered Virieo Perception and a new app for streaming your games called Intugame. Intugame also had head tracking. I was able to get Skyrim going with Intugame and Virieo on my Google Cardboard but the image was too tall with either the sbs setting or DIYrift setting in Virieo. I then found a forum with some edits to the sidebysiderift.fx file in one of the virieo folders that made the image the correct aspect ratio but only showed 80% of the image so the sides were cut off. I didn't like that but I could see some potential here for creating my own iphone rift. I was able to change some numbers and fix the image significantly. I will share those settings at the end of my saga. I then bought a cheap plastic "google cardboard" called ritech II or iMax 3D with a head strap. That was not a good purchase. It gave me a clearer picture than the google cardboard with no distortion but the picture was so small in front of my face that I might as well have just been looking at my monitor. Field of view is super important when you're trying to get immersed into a game. So I hunted around and broke down and bought a Zeiss VR One. Wow. What a difference. It's comfortable and has a pretty great field of view and a much better picture than the google cardboard. Now back to the streaming software. After playing around with Gagagu Streamer and Intugame I found that Gagagu Streamer gave a much better picture at a higher frame rate than Intugame but had no head tracking. The developer is currently working on that. So I tried a few games with both streamers and It was just O.K. The frame rate was just too slow and I was really wishing that I could use a direct connection to my computer to get the frame rate up but I don't think that's possible right now. Then I made a discovery that made me feel like a real idiot. My iphone was connected to my router at 2.4 GHz instead of 5GHz. Once I changed that, the frame rate jumped up to a very playable level. I am so excited that I can play my games in immersive 3D on my phone! I know it's no Oculus Rift but it sure will do for now.
Here are my settings in the sidebysiderift.fx file in the fx folder in your Virieo folder. These settings are good for a Zeiss VR One but you can easily edit some numbers for your hmd:
// Combines two images into one warped Side-by-Side image
sampler2D TexMap0;
sampler2D TexMap1;
float2 Warp(float2 Tex : TEXCOORD0)
{
float2 newPos = Tex;
float c = -81.0f/15.0f;
float u = Tex.x*2.0f - 1.0f;
float v = Tex.y*2.0f - 1.0f;
newPos.x = c*u/(pow(v, 2) + c);
newPos.y = c*v/(pow(u, 2) + c);
newPos.x = (newPos.x + 1.0f)*0.5f;
newPos.y = (newPos.y + 1.0f)*0.5f;
return newPos;
}
float4 SBSRift(float2 Tex : TEXCOORD0) : COLOR
{
float4 tColor;
float2 newPos = Tex;
float2 warpedTexCoord;
// This is all pretty lazy, I haven't generalised for a variable vertical percentage so it's fixed at 80%.
//float screenRatio = 1.6f // 16:10 screen, use 1.777777777f for 16:9 screen
//float visibleRatio = 1f; // 16:10 screen, use 0.9f for 16:9 screen. These numbers would need to change
// for a different vertical %. I've left all those calculations out
// These numbers are constants for the screen size and a given vertical usage, so rather than calculating them for every pixel
// I'm just putting the number directly into xRangeToUse. Normally this would be done outside the shader
// and passed in.
float xRangeToUse = 0.625f; //visibleRatio / screenRatio;
float xHalfOfRangeNottoUse = 0.1875f; // (1f - xRangeToUse) * 0.5f;
newPos.y = newPos.y * 1.25f - 0.125f; // 80% of vertical.
if(newPos.x < 0.5)
{
newPos.x = (newPos.x * 2.0f * xRangeToUse) + xHalfOfRangeNottoUse;
warpedTexCoord = Warp(newPos);
tColor = tex2D(TexMap0, warpedTexCoord);
}
else
{
newPos.x = (((newPos.x - 0.5f) * 2.0f)* xRangeToUse) + xHalfOfRangeNottoUse;
warpedTexCoord = Warp(newPos);
tColor = tex2D(TexMap1, warpedTexCoord);
}
// remove everything between here and the next comment except "return tColor;" if you want the clamped texture around the edge instead of black
if ((warpedTexCoord.y > 1.0f) || (warpedTexCoord.y < 0.0f)) {
return 0;
}
else {
return tColor;
}
// This is the next comment
}
technique ViewShader
{
pass P0
{
VertexShader = null;
PixelShader = compile ps_2_0 SBSRift();
}
}
Near the top of that code you see the line "float c = -81.0f/15.0f;" If you change that "15" it will change the amount of distortion for the image.
Soon after that are the lines
newPos.x = c*u/(pow(v, 2) + c);
newPos.y = c*v/(pow(u, 2) + c);
You can add a multiplier after the last "c" to increase or reduce the overall image size.
For example:
newPos.x = c*u/(pow(v, 2) + c*2.0);
newPos.y = c*v/(pow(u, 2) + c*2.0);
This will double the image size filling up your screen but cutting out a significant amount of the image.
If you want to make the image smaller, you could do something like this:
newPos.x = c*u/(pow(v, 2) + c*0.75);
newPos.y = c*v/(pow(u, 2) + c*0.75);
I hope all of this information helps someone get their own iphone rift going! Good luck!
Here are my settings in the sidebysiderift.fx file in the fx folder in your Virieo folder. These settings are good for a Zeiss VR One but you can easily edit some numbers for your hmd:
Code: Select all
sampler2D TexMap0;
sampler2D TexMap1;
float2 Warp(float2 Tex : TEXCOORD0)
{
float2 newPos = Tex;
float c = -81.0f/15.0f;
float u = Tex.x*2.0f - 1.0f;
float v = Tex.y*2.0f - 1.0f;
newPos.x = c*u/(pow(v, 2) + c);
newPos.y = c*v/(pow(u, 2) + c);
newPos.x = (newPos.x + 1.0f)*0.5f;
newPos.y = (newPos.y + 1.0f)*0.5f;
return newPos;
}
float4 SBSRift(float2 Tex : TEXCOORD0) : COLOR
{
float4 tColor;
float2 newPos = Tex;
float2 warpedTexCoord;
// This is all pretty lazy, I haven't generalised for a variable vertical percentage so it's fixed at 80%.
//float screenRatio = 1.6f // 16:10 screen, use 1.777777777f for 16:9 screen
//float visibleRatio = 1f; // 16:10 screen, use 0.9f for 16:9 screen. These numbers would need to change
// for a different vertical %. I've left all those calculations out
// These numbers are constants for the screen size and a given vertical usage, so rather than calculating them for every pixel
// I'm just putting the number directly into xRangeToUse. Normally this would be done outside the shader
// and passed in.
float xRangeToUse = 0.625f; //visibleRatio / screenRatio;
float xHalfOfRangeNottoUse = 0.1875f; // (1f - xRangeToUse) * 0.5f;
newPos.y = newPos.y * 1.25f - 0.125f; // 80% of vertical.
if(newPos.x < 0.5)
{
newPos.x = (newPos.x * 2.0f * xRangeToUse) + xHalfOfRangeNottoUse;
warpedTexCoord = Warp(newPos);
tColor = tex2D(TexMap0, warpedTexCoord);
}
else
{
newPos.x = (((newPos.x - 0.5f) * 2.0f)* xRangeToUse) + xHalfOfRangeNottoUse;
warpedTexCoord = Warp(newPos);
tColor = tex2D(TexMap1, warpedTexCoord);
}
// remove everything between here and the next comment except "return tColor;" if you want the clamped texture around the edge instead of black
if ((warpedTexCoord.y > 1.0f) || (warpedTexCoord.y < 0.0f)) {
return 0;
}
else {
return tColor;
}
// This is the next comment
}
technique ViewShader
{
pass P0
{
VertexShader = null;
PixelShader = compile ps_2_0 SBSRift();
}
}
Code: Select all
Near the top of that code you see the line "float c = -81.0f/15.0f;" If you change that "15" it will change the amount of distortion for the image.
Soon after that are the lines
newPos.x = c*u/(pow(v, 2) + c);
newPos.y = c*v/(pow(u, 2) + c);
You can add a multiplier after the last "c" to increase or reduce the overall image size.
For example:
newPos.x = c*u/(pow(v, 2) + c*2.0);
newPos.y = c*v/(pow(u, 2) + c*2.0);
This will double the image size filling up your screen but cutting out a significant amount of the image.
If you want to make the image smaller, you could do something like this:
newPos.x = c*u/(pow(v, 2) + c*0.75);
newPos.y = c*v/(pow(u, 2) + c*0.75);
I hope all of this information helps someone get their own iphone rift going! Good luck!