Ejemplo n.º 1
0
    // Builds a tessellated grid of quads across the provided bounds with three sets of UVs used to account for
    // lens distortion and chromatic aberration.
    public static Mesh CreateDistortMesh(SteamVR.IHmd hmd, SteamVR.Hmd_Eye eye, int resU, int resV, Rect bounds)
    {
        int numVerts = resU * resV;
        var vertices = new Vector3[numVerts];
        var redUVs   = new Vector3[numVerts];
        var greenUVs = new Vector2[numVerts];
        var blueUVs  = new Vector2[numVerts];

        int iTri      = 0;
        int resUm1    = resU - 1;
        int resVm1    = resV - 1;
        var triangles = new int[2 * 3 * resUm1 * resVm1];

        for (int iV = 0; iV < resV; iV++)
        {
            float v = (float)iV / resVm1;
            float y = SteamVR_Utils.Lerp(bounds.yMax, bounds.yMin, v);             // ComputeDistortion expects 0,0 in upper left
            for (int iU = 0; iU < resU; iU++)
            {
                float u      = (float)iU / resUm1;
                float x      = SteamVR_Utils.Lerp(bounds.xMin, bounds.xMax, u);
                var   coords = hmd.ComputeDistortion(eye, u, v);

                int idx = iV * resU + iU;
                vertices[idx] = new Vector3(x, y, 0.1f);

                redUVs[idx]   = new Vector3(coords.rfRed[0], 1.0f - coords.rfRed[1], 0);
                greenUVs[idx] = new Vector2(coords.rfGreen[0], 1.0f - coords.rfGreen[1]);
                blueUVs[idx]  = new Vector2(coords.rfBlue[0], 1.0f - coords.rfBlue[1]);

                if (iV > 0 && iU > 0)
                {
                    int a = (iV - 1) * resU + (iU - 1);
                    int b = (iV - 1) * resU + iU;
                    int c = iV * resU + (iU - 1);
                    int d = iV * resU + iU;

                    triangles[iTri++] = a;
                    triangles[iTri++] = b;
                    triangles[iTri++] = d;

                    triangles[iTri++] = a;
                    triangles[iTri++] = d;
                    triangles[iTri++] = c;
                }
            }
        }

        var mesh = new Mesh();

        mesh.vertices  = vertices;
        mesh.normals   = redUVs;       // stuff data in normals since only two uv sets exposed
        mesh.uv        = greenUVs;
        mesh.uv2       = blueUVs;
        mesh.triangles = triangles;
        return(mesh);
    }
Ejemplo n.º 2
0
    public void Init(SteamVR_Camera tracker, SteamVR.Hmd_Eye eye, float depth)
    {
        this.tracker = tracker;
        this.eye     = eye;

        var hmd = SteamVR.IHmd.instance;
        var i   = (int)eye;

        uint x = 0, y = 0, w = 0, h = 0;

        hmd.GetEyeOutputViewport(eye, ref x, ref y, ref w, ref h);

        overlaySettings.kernel = new Vector3[] {         // AA sub-pixel sampling (2x2 RGSS)
            new Vector3(0.125f / w, -0.375f / h, 0),
            new Vector3(0.375f / w, 0.125f / h, 0),
            new Vector3(-0.125f / w, 0.375f / h, 0),
            new Vector3(-0.375f / w, -0.125f / h, 0)
        };

        float left = 0.0f, right = 0.0f, top = 0.0f, bottom = 0.0f;

        hmd.GetProjectionRaw(eye, ref left, ref right, ref top, ref bottom);

        var   camera = GetComponent <Camera>();
        float zFar   = camera.farClipPlane;
        float zNear  = camera.nearClipPlane;

        var m = Matrix4x4.identity;

        float idx = 1.0f / (right - left);
        float idy = 1.0f / (bottom - top);
        float idz = 1.0f / (zFar - zNear);
        float sx  = right + left;
        float sy  = bottom + top;

        m[0, 0] = 2 * idx; m[0, 1] = 0;     m[0, 2] = sx * idx;    m[0, 3] = 0;
        m[1, 0] = 0;     m[1, 1] = 2 * idy; m[1, 2] = sy * idy;    m[1, 3] = 0;
        m[2, 0] = 0;     m[2, 1] = 0;     m[2, 2] = -zFar * idz; m[2, 3] = -zFar * zNear * idz;
        m[3, 0] = 0;     m[3, 1] = 0;     m[3, 2] = -1.0f;     m[3, 3] = 0;

        camera.projectionMatrix = m;
        camera.depth            = depth;                                // enforce rendering order
        camera.eventMask        = 0;                                    // disable mouse events
        camera.orthographic     = false;                                // force perspective
        camera.aspect           = (float)w / h;

        // Use fov of projection matrix (which is grown to account for non-linear undistort)
        camera.fieldOfView = (Mathf.Atan(bottom) - Mathf.Atan(top)) * Mathf.Rad2Deg;

        // Copy and clear clearFlags to avoid duplicate work.
        if ((int)clearFlags == 0)
        {
            clearFlags        = camera.clearFlags;
            camera.clearFlags = CameraClearFlags.Nothing;
        }

        camera.targetTexture = SteamVR_Camera.sceneTexture;

        overlaySettings.invProj = m.inverse;

        transform.parent     = tracker.offset;
        transform.localScale = Vector3.one;

        var t = new SteamVR_Utils.RigidTransform(hmd.GetHeadFromEyePose(eye));

        transform.localPosition = t.pos;
        transform.localRotation = t.rot;

        if (distortMesh[i] == null)
        {
            var viewportWidth  = SteamVR_Camera.viewportTexture.width;
            var viewportHeight = SteamVR_Camera.viewportTexture.height;

            var eyeViewport = new Rect(
                2.0f * x / viewportWidth - 1.0f,
                2.0f * y / viewportHeight - 1.0f,
                2.0f * w / viewportWidth,
                2.0f * h / viewportHeight);

            distortMesh[i] = SteamVR_Utils.CreateDistortMesh(hmd, eye, 32, 32, eyeViewport);
        }
    }