예제 #1
0
 private void SetShaderGlobals()
 {
     // For any shaders that want to use these numbers for distortion correction.  But only
     // if distortion correction is needed, yet not already being handled by another method.
     if (GvrViewer.Instance.VRModeEnabled &&
         GvrViewer.Instance.DistortionCorrection == GvrViewer.DistortionCorrectionMethod.None)
     {
         GvrProfile p = GvrViewer.Instance.Profile;
         // Distortion vertex shader currently setup for only 6 coefficients.
         if (p.viewer.inverse.Coef.Length > 6)
         {
             Debug.LogWarning("Inverse distortion correction has more than 6 coefficents. "
                              + "Shader only supports 6.");
         }
         Matrix4x4 mat = new Matrix4x4()
         {
         };
         for (int i = 0; i < p.viewer.inverse.Coef.Length; i++)
         {
             mat[i] = p.viewer.inverse.Coef[i];
         }
         Shader.SetGlobalMatrix("_Undistortion", mat);
         float[] rect = new float[4];
         p.GetLeftEyeVisibleTanAngles(rect);
         float r = GvrProfile.GetMaxRadius(rect);
         Shader.SetGlobalFloat("_MaxRadSq", r * r);
     }
 }
예제 #2
0
    private static void ComputeMeshPoints(int width, int height, bool distortVertices,
                                          out Vector3[] vertices, out Vector2[] tex)
    {
        float[]    lensFrustum   = new float[4];
        float[]    noLensFrustum = new float[4];
        Rect       viewport;
        GvrProfile profile = GvrViewer.Instance.Profile;

        profile.GetLeftEyeVisibleTanAngles(lensFrustum);
        profile.GetLeftEyeNoLensTanAngles(noLensFrustum);
        viewport = profile.GetLeftEyeVisibleScreenRect(noLensFrustum);
        vertices = new Vector3[2 * width * height];
        tex      = new Vector2[2 * width * height];
        for (int e = 0, vidx = 0; e < 2; e++)
        {
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++, vidx++)
                {
                    float u = (float)i / (width - 1);
                    float v = (float)j / (height - 1);
                    float s, t; // The texture coordinates in StereoScreen to read from.
                    if (distortVertices)
                    {
                        // Grid points regularly spaced in StreoScreen, and barrel distorted in the mesh.
                        s = u;
                        t = v;
                        float x = Mathf.Lerp(lensFrustum[0], lensFrustum[2], u);
                        float y = Mathf.Lerp(lensFrustum[3], lensFrustum[1], v);
                        float d = Mathf.Sqrt(x * x + y * y);
                        float r = profile.viewer.distortion.distortInv(d);
                        float p = x * r / d;
                        float q = y * r / d;
                        u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]);
                        v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]);
                    }
                    else
                    {
                        // Grid points regularly spaced in the mesh, and pincushion distorted in
                        // StereoScreen.
                        float p = Mathf.Lerp(noLensFrustum[0], noLensFrustum[2], u);
                        float q = Mathf.Lerp(noLensFrustum[3], noLensFrustum[1], v);
                        float r = Mathf.Sqrt(p * p + q * q);
                        float d = profile.viewer.distortion.distort(r);
                        float x = p * d / r;
                        float y = q * d / r;
                        s = Mathf.Clamp01((x - lensFrustum[0]) / (lensFrustum[2] - lensFrustum[0]));
                        t = Mathf.Clamp01((y - lensFrustum[3]) / (lensFrustum[1] - lensFrustum[3]));
                    }
                    // Convert u,v to mesh screen coordinates.
                    float aspect = profile.screen.width / profile.screen.height;
                    u = (viewport.x + u * viewport.width - 0.5f) * aspect;
                    v = viewport.y + v * viewport.height - 0.5f;
                    vertices[vidx] = new Vector3(u, v, 1);
                    // Adjust s to account for left/right split in StereoScreen.
                    s         = (s + e) / 2;
                    tex[vidx] = new Vector2(s, t);
                }
            }
            float w = lensFrustum[2] - lensFrustum[0];
            lensFrustum[0] = -(w + lensFrustum[0]);
            lensFrustum[2] = w - lensFrustum[2];
            w = noLensFrustum[2] - noLensFrustum[0];
            noLensFrustum[0] = -(w + noLensFrustum[0]);
            noLensFrustum[2] = w - noLensFrustum[2];
            viewport.x       = 1 - (viewport.x + viewport.width);
        }
    }