SteamVR Developer Hardware

SteamVR Developer Hardware

Creo 9 MAR 2016 a las 1:05
Rendering portals in Unity 5.4 with native OpenVR?
Has anyone worked out a good way to render a portal with native OpenVR? Previously I was positioning a camera based on each eye position and rendering once for each eye to a RenderTexture. Since the stereo rendering is done natively now, that approach no longer works. I've been experimenting for the past couple hours and I haven't come up with a solution yet. Surely I'm missing something here. Or is it not currently possible to render a portal with native OpenVR?
< >
Mostrando 16-21 de 21 comentarios
railboy 10 MAR 2016 a las 15:26 
Publicado originalmente por Creo:
Done! No need for duplicating cameras or portals or layers! And you get to keep the performance benefits of native OpenVR integration on your main VR camera.

Wow, NICE! Trying it now.
yezzer 11 MAR 2016 a las 5:20 
Does anyone have a suitable shader they could share? I'd love to give this a go :)
Creo 11 MAR 2016 a las 10:33 
Publicado originalmente por yezzer:
Does anyone have a suitable shader they could share? I'd love to give this a go :)
Railboy posted his mirrors project originally on github, so that's where I would suggest starting.
https://github.com/AADProductions/VR-Mirrors

In his shader (https://github.com/AADProductions/VR-Mirrors/blob/master/Assets/MirrorEffect/PostEffectMirrorReflections.shader) you would just need to change the properties block to look something like this:

Properties { _LeftEyeTexture ("Left Eye Texture", 2D) = "white" {} _RightEyeTexture ("Right Eye Texture", 2D) = "white" {} }

And then change the _MirrorTexture var and the surf function down below to this:
sampler2D _LeftEyeTexture; sampler2D _RightEyeTexture; void surf (Input IN, inout SurfaceOutput o) { float2 screenUV = IN.screenPos.xy / IN.screenPos.w; if (unity_CameraProjection[0][2] < 0) { o.Albedo = tex2D(_LeftEyeTexture, screenUV).rgb; } else { o.Albedo = tex2D(_RightEyeTexture, screenUV).rgb; } o.Alpha = 1; }
76561198127749705 4 AGO 2016 a las 9:19 
The one thing this code is missing is adjusting the near clip plane to exclude things behind the portal/mirror. I'm using this in my project right now, and things that are behind my mirror appear in the mirror when I get a certain distance from it.

There is a way to fix it using oblique frustum clipping, which I have done. The code for this technique (C++ but easily ported) exists here: {ENLACE ELIMINADO}

You'll need a clip plane, calculated with a method like this:

private Vector4 CameraSpacePlane (Camera cam, Vector3 pos, Vector3 normal, float sideSign) { Vector3 offsetPos = pos + normal * m_ClipPlaneOffset; Matrix4x4 m = cam.worldToCameraMatrix; Vector3 cpos = m.MultiplyPoint( offsetPos ); Vector3 cnormal = m.MultiplyVector( normal ).normalized * sideSign; return new Vector4( cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos,cnormal) ); }

so in the RenderIntoMaterial method you will want to do this (I added the public float clipPlaneOffset):

Vector4 clipPlane = CameraSpacePlane(cameraForPortal, ReflectionTransform.position, ReflectionTransform.forward, 1.0f, clipPlaneOffset);

In each of the paths for Left/Right eye when rendering as a mirror:
Matrix4x4 projection = HMDMatrix4x4ToMatrix4x4(SteamVR.instance.hmd.GetProjectionMatrix(Valve.VR.EVREye.Eye_Left, VrEye.nearClipPlane, VrEye.farClipPlane, Valve.VR.EGraphicsAPIConvention.API_DirectX)) * Matrix4x4.Scale(mirrorMatrixScale); ModifyProjectionMatrix(ref projection, clipPlane);

Then assign the camera matrix:

cameraForPortal.projectionMatrix = projection;

Do that same thing using Valve.VR.EVREye.Eye_Right for the right eye and you should be good.


Edit: adding the modify code.

static float Sign(float x) { if (x > 0.0F) return (1.0F); if (x < 0.0F) return (-1.0F); return (0.0F); } public static void ModifyProjectionMatrix(ref Matrix4x4 projection, Vector4 clipPlane) { // Calculate the clip-space corner point opposite the clipping plane // using Equation (5.64) and transform it into camera space by // multiplying it by the inverse of the projection matrix. Vector4 q = projection.inverse * new Vector4( (Sign(clipPlane.x) + projection[8]) / projection[0], (Sign(clipPlane.y) + projection[9]) / projection[5], 1.0f, (1.0f + projection[10]) / projection[14] ); // Calculate the scaled plane vector using Equation (5.68) // and replace the third row of the projection matrix. Vector4 c = clipPlane * (2.0F / (Vector4.Dot(clipPlane, q))); projection[2] = c.x; projection[6] = c.y; projection[10] = c.z + 1; projection[14] = c.w; }
Última edición por playfulmike; 4 AGO 2016 a las 9:28
Senor Tron 9 AGO 2016 a las 0:28 
Thanks heaps for sharing this, after I got my head around it I have been having a lot of fun with it using it to create portals between areas. I thought that the 1024 render texture would give a noticeable downgrade in image quality but have been using it to make portals you teleport through and the transition is basically invisible.
JKant 10 NOV 2016 a las 19:49 
I tried to implement this fix for a volumetric light effect that was also broken when using Unity's integrated VR support. But unity_CameraProjection[0][2] seems to always be zero in the shader?
Última edición por JKant; 10 NOV 2016 a las 20:06
< >
Mostrando 16-21 de 21 comentarios
Por página: 1530 50

Publicado el: 9 MAR 2016 a las 1:05
Mensajes: 21