示例#1
0
    void CubemapToEnvMap()
    {
        Texture2D resultTex = new Texture2D(m_DstTexSize, m_DstTexSize, TextureFormat.RGB24, false);
        float     invTexRes = 1.0f / (resultTex.height - 1);

        //bool		topHemisphere = true;

        for (int y = 0; y < resultTex.height; y++)
        {
            for (int x = 0; x < resultTex.width; x++)
            {
                Vector3 dir;

                float xf = (float)x * invTexRes;
                float yf = (float)y * invTexRes;

                xf = xf * 2 - 1;
                yf = yf * 2 - 1;

                float p = 0.5f - 0.5f * (xf * xf + yf * yf);

                dir.x = xf;
                dir.y = p;
                dir.z = yf;

                dir.Normalize();


//				float theta	= 2 * Mathf.Acos(Mathf.Sqrt(1 - xf));
//				float phi	= topHemisphere ? (Mathf.PI * yf) : (2 * Mathf.PI * yf);

//				dir.x = Mathf.Sin(theta) * Mathf.Cos(phi);
//				dir.y = Mathf.Sin(theta) * Mathf.Sin(phi);
//				dir.z = Mathf.Cos(theta);

                CubemapFace face;
                float       u, v;

                DirToUV(dir, out face, out u, out v);

                Color col = m_Cubemap.GetPixel(face, (int)(u * m_Cubemap.width), (int)(v * m_Cubemap.height));

                resultTex.SetPixel(x, y, col);
            }
        }

        resultTex.Apply();

        SaveTex(resultTex, "Assets/GeneratedTextures/envmap.png");
    }
示例#2
0
    Vector4 GetCubeColor(Vector3 pos)
    {
        Color col = new Color();
        //可以使用正态分布

        float   xabs      = pos.x;
        float   yabs      = pos.y;
        float   zabs      = pos.z;
        int     faceIndex = -1;
        Vector2 uv        = new Vector2();

        if (xabs >= yabs && xabs >= zabs)
        {
            //x
            faceIndex = pos.x > 0 ? 0 : 1;
            uv.x      = pos.y / xabs;
            uv.y      = pos.z / xabs;
        }
        else if (yabs >= xabs && yabs >= zabs)
        {
            //y
            faceIndex = pos.y > 0 ? 2 : 3;
            uv.x      = pos.x / yabs;
            uv.y      = pos.z / yabs;
        }
        else
        {
            //z
            faceIndex = pos.z > 0 ? 4 : 5;
            uv.x      = pos.x / zabs;
            uv.y      = pos.y / zabs;
        }
        //[0,1.0]
        uv.x = (uv.x + 1.0f) / 2.0f;
        uv.y = (uv.y + 1.0f) / 2.0f;
        int w = cubeMap.width - 1;
        int x = (int)(w * uv.x);
        int y = (int)(w * uv.y);

        //Debug.Log("random face:" + faceIndex.ToString());
        if (faceCalculate.ContainsKey(faceIndex))
        {
            faceCalculate[faceIndex]++;
        }
        col = cubeMap.GetPixel((CubemapFace)faceIndex, x, y);
        Vector4 colVec4 = new Vector4(col.r, col.g, col.b, col.a);

        return(colVec4);
    }
示例#3
0
    /// <summary>
    ///保存单张图片
    /// </summary>
    private void SaveSingelTexture()
    {
        Texture2D screenShot = new Texture2D(renderCubeMap.width,
                                             renderCubeMap.height,
                                             TextureFormat.ARGB32,
                                             false);

        for (int i = 0; i < renderCubeMap.width; i++)
        {
            for (int j = 0; j < renderCubeMap.height; j++)
            {
                screenShot.SetPixel(i, j, renderCubeMap.GetPixel(offcialFaces, renderCubeMap.width - i, renderCubeMap.height - j));
            }
        }

        screenShot.Apply();
        byte[] bytes = screenShot.EncodeToPNG();

        string path = EditorUtility.SaveFilePanel("图片保存", Application.dataPath, faces.ToString(), "png");

        System.IO.File.WriteAllBytes(path, bytes);

        AssetDatabase.Refresh();
    }
示例#4
0
    void BackUpAndScaleAndFormatAndSizeAndCopyCubeTexture(List <Cubemap> cubeMapGroup, int maxSize)
    {
        for (int i = 0; i < cubeMapGroup.Count; i++)
        {
            string fileName = CopyTextureToFolder(cubeMapGroup[i].GetInstanceID(), tempTextureFolderFinal, true);
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);

            TextureImporter textureImporter = (TextureImporter)TextureImporter.GetAtPath(fileName);
            textureImporter.textureShape       = TextureImporterShape.TextureCube;
            textureImporter.isReadable         = true;
            textureImporter.maxTextureSize     = maxSize;
            textureImporter.mipmapEnabled      = false;
            textureImporter.wrapMode           = TextureWrapMode.Clamp;
            textureImporter.filterMode         = FilterMode.Point;
            textureImporter.textureCompression = TextureImporterCompression.Uncompressed;

            AssetDatabase.ImportAsset(fileName);
            Cubemap loadTex = (Cubemap)AssetDatabase.LoadAssetAtPath(fileName, typeof(Cubemap));

            Texture2D exportSaveTex;
            exportSaveTex = new Texture2D(loadTex.width, loadTex.height, TextureFormat.RGB24, false, false);

            for (int j = 0; j < 6; j++)
            {
                for (int k = 0; k < exportSaveTex.width; k++)
                {
                    for (int z = 0; z < exportSaveTex.height; z++)
                    {
                        exportSaveTex.SetPixel(k, exportSaveTex.height - z - 1, loadTex.GetPixel((CubemapFace)j, k, z));
                    }
                }
//              exportSaveTex.SetPixels(loadTex.GetPixels((CubemapFace)j));
                exportSaveTex.Apply();
                var bytes = exportSaveTex.EncodeToJPG(95);
                File.WriteAllBytes(textureFolderFinal + "/" + loadTex.name + "_" + j + ".jpg", bytes);
            }
        }
    }
    public static int GetPixel(IntPtr l)
    {
        int result;

        try
        {
            Cubemap     cubemap = (Cubemap)LuaObject.checkSelf(l);
            CubemapFace face;
            LuaObject.checkEnum <CubemapFace>(l, 2, out face);
            int x;
            LuaObject.checkType(l, 3, out x);
            int y;
            LuaObject.checkType(l, 4, out y);
            Color pixel = cubemap.GetPixel(face, x, y);
            LuaObject.pushValue(l, true);
            LuaObject.pushValue(l, pixel);
            result = 2;
        }
        catch (Exception e)
        {
            result = LuaObject.error(l, e);
        }
        return(result);
    }
        // Start is called before the first frame update
        void Start()
        {
            query     = new KDQuery();
            VPLVector = new Vector3[InitVPLCount];
            VPLPoints = new Vector3[InitVPLCount];
            SpotAngle = GetComponent <Light>().spotAngle;
            if (type == "Point Light")
            {
                Vector3    org = this.transform.position;
                RaycastHit hit;
                parent = new GameObject();
                for (int i = 0; i < InitVPLCount; i++)
                {
                    float Rx = Random48.Get();
                    float Ry = Random48.Get();
                    float Rz = Random48.Get();
                    Rx        = halton(seedCount, 2);
                    Ry        = halton(seedCount, 3);
                    Rz        = halton(seedCount++, 4);
                    seedCount = seedCount % (maxSeed * 3);
                    Vector3 tempDir = new Vector3(Rx * 2.0f - 1.0f, Ry * 2.0f - 1.0f, Rz * 2.0f - 1.0f);
                    //tempDir.Normalize();
                    //tempDir -= new Vector3(0.5f,0.5f,0.5f);
                    VPLVector[i] = (tempDir);
                    Vector3 B   = tempDir;
                    Vector3 dir = this.transform.right * B.x + this.transform.up * B.y - this.transform.forward * B.z;
                    if (Physics.Raycast(org, dir, out hit, 1000))
                    {
                        VPLPoints[i] = (hit.point);
                    }
                    GameObject temp = new GameObject();
                    temp.transform.parent   = parent.transform;
                    temp.transform.position = VPLPoints[i];
                    temp.AddComponent <Light>();
                    temp.GetComponent <Light>().shadows          = LightShadows.Hard;
                    temp.GetComponent <Light>().shadowBias       = 0;
                    temp.GetComponent <Light>().shadowNormalBias = 0;
                    temp.GetComponent <Light>().shadowNearPlane  = 0.2f;
                    Vector3 CubeUV = convert_xyz_to_cube_uv(B);
                    if (CubeUV.x == 0.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveX, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 1.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeX, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 2.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveY, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 3.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeY, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 4.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveZ, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 5.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeZ, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    VPL.Add(temp);
                }
            }
            else
            {
                int        PassCount = 0;
                Vector3    org       = this.transform.position;
                RaycastHit hit;
                Texture2D  tempTex = new Texture2D(1024, 1024);
                RenderTexture.active = rendertexture;
                tempTex.ReadPixels(new UnityEngine.Rect(0, 0, 1024, 1024), 0, 0);
                parent = new GameObject();
                Debug.DrawLine(transform.position + transform.forward * 10, this.transform.position);
                while (PassCount != InitVPLCount)
                {
                    //float Rx = ((float)Random.Range(0, 1024)) / 1024.0f;
                    //float Ry = ((float)Random.Range(0, 1024)) / 1024.0f;

                    float Rx = Random48.Get();
                    float Ry = Random48.Get();
                    Rx        = halton(seedCount, 2);
                    Ry        = halton(seedCount++, 3);
                    seedCount = seedCount % (maxSeed * 2);
                    if (Mathf.Sqrt((Rx - 0.5f) * (Rx - 0.5f) + (Ry - 0.5f) * (Ry - 0.5f)) <= radius)
                    {
                        Vector3 B = new Vector2(Rx, Ry);
                        B.x -= 0.5f;
                        B.y -= 0.5f;
                        VPLVector[PassCount] = B;
                        //            float l = Vector3.Dot(B, B);
                        float z;
                        z = -Mathf.Tan((Fov / 2.0f) / 180.0f * 3.1415926f);

                        Vector3 dir = this.transform.right * B.x + this.transform.up * B.y - this.transform.forward * z;

                        if (Physics.Raycast(org, dir, out hit, 1000))
                        {
                            Vector3 p;
                            p.x = B.x * 1024.0f;
                            p.y = B.y * 1024.0f;

                            GameObject temp = new GameObject();
                            temp.transform.parent   = parent.transform;
                            temp.transform.position = hit.point;
                            temp.AddComponent <Light>();
                            temp.GetComponent <Light>().color   = (tempTex.GetPixel((int)p.x, (int)p.y));
                            temp.GetComponent <Light>().shadows = LightShadows.Hard;
                            VPL.Add(temp);
                            VPLPoints[PassCount] = hit.point;
                            PassCount++;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                int a = 1;
                tree = new KDTree(VPLPoints, 16);
            }
        }
示例#7
0
        void Update()
        {
            if (cubemapType == CubemapType.SkyboxCubemap)
            {
                messageSkybox = true;
                messageClouds = false;
            }
            else
            {
                messageSkybox = false;
                messageClouds = true;
            }

            if (generateCubemap)
            {
                var cam = GetComponent <Camera>();

                var path = "Assets/Generated Skybox Cubemap.png";

                if (cubemapType == CubemapType.CloudsCubemap)
                {
                    path = "Assets/Generated Clouds Cubemap.png";
                }

                Cubemap cubemap = new Cubemap((int)cubemapSize, UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat, 0);

                cam.RenderToCubemap(cubemap);
                cubemap.Apply();

                Texture2D img = new Texture2D((int)cubemapSize * 6, (int)cubemapSize, TextureFormat.RGBAFloat, false);

                for (int i = 0; i < (int)cubemapSize; i++)
                {
                    for (int j = 0; j < (int)cubemapSize; j++)
                    {
                        var pixelColor = cubemap.GetPixel(CubemapFace.PositiveX, i, (int)cubemapSize - j);
                        var pixelValue = 1.0f;

                        if (cubemapType == CubemapType.CloudsCubemap)
                        {
                            pixelValue = pixelColor.r + pixelColor.g + pixelColor.b;
                        }

                        img.SetPixel(i, j, new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelValue));
                    }
                }

                for (int i = 0; i < (int)cubemapSize; i++)
                {
                    for (int j = 0; j < (int)cubemapSize; j++)
                    {
                        var pixelColor = cubemap.GetPixel(CubemapFace.NegativeX, i, (int)cubemapSize - j);
                        var pixelValue = 1.0f;

                        if (cubemapType == CubemapType.CloudsCubemap)
                        {
                            pixelValue = pixelColor.r + pixelColor.g + pixelColor.b;
                        }

                        img.SetPixel(i + (int)cubemapSize, j, new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelValue));
                    }
                }

                for (int i = 0; i < (int)cubemapSize; i++)
                {
                    for (int j = 0; j < (int)cubemapSize; j++)
                    {
                        var pixelColor = cubemap.GetPixel(CubemapFace.PositiveY, i, (int)cubemapSize - j);
                        var pixelValue = 1.0f;

                        if (cubemapType == CubemapType.CloudsCubemap)
                        {
                            pixelValue = pixelColor.r + pixelColor.g + pixelColor.b;
                        }

                        img.SetPixel(i + (int)cubemapSize * 2, j, new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelValue));
                    }
                }

                for (int i = 0; i < (int)cubemapSize; i++)
                {
                    for (int j = 0; j < (int)cubemapSize; j++)
                    {
                        var pixelColor = cubemap.GetPixel(CubemapFace.NegativeY, i, (int)cubemapSize - j);
                        var pixelValue = 1.0f;

                        if (cubemapType == CubemapType.CloudsCubemap)
                        {
                            pixelValue = pixelColor.r + pixelColor.g + pixelColor.b;
                        }

                        img.SetPixel(i + (int)cubemapSize * 3, j, new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelValue));
                    }
                }

                for (int i = 0; i < (int)cubemapSize; i++)
                {
                    for (int j = 0; j < (int)cubemapSize; j++)
                    {
                        var pixelColor = cubemap.GetPixel(CubemapFace.PositiveZ, i, (int)cubemapSize - j);
                        var pixelValue = 1.0f;

                        if (cubemapType == CubemapType.CloudsCubemap)
                        {
                            pixelValue = pixelColor.r + pixelColor.g + pixelColor.b;
                        }

                        img.SetPixel(i + (int)cubemapSize * 4, j, new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelValue));
                    }
                }

                for (int i = 0; i < (int)cubemapSize; i++)
                {
                    for (int j = 0; j < (int)cubemapSize; j++)
                    {
                        var pixelColor = cubemap.GetPixel(CubemapFace.NegativeZ, i, (int)cubemapSize - j);
                        var pixelValue = 1.0f;

                        if (cubemapType == CubemapType.CloudsCubemap)
                        {
                            pixelValue = pixelColor.r + pixelColor.g + pixelColor.b;
                        }

                        img.SetPixel(i + (int)cubemapSize * 5, j, new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelValue));
                    }
                }

                img.Apply();

                byte[] imgBytes = img.EncodeToPNG();
                File.WriteAllBytes(path, imgBytes);

                AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

                TextureImporter texImporter = AssetImporter.GetAtPath(path) as TextureImporter;
                texImporter.textureShape       = TextureImporterShape.TextureCube;
                texImporter.textureCompression = TextureImporterCompression.CompressedHQ;
                texImporter.mipmapEnabled      = false;
                texImporter.sRGBTexture        = false;

                texImporter.SaveAndReimport();

                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                if (cubemapType == CubemapType.CloudsCubemap)
                {
                    RenderSettings.skybox.SetTexture("_CloudsCubemap", AssetDatabase.LoadAssetAtPath <Cubemap>(path));
                }

                Debug.Log("[Polyverse Skies] The Generated Cubemap is saved to the Assets folder!");

                generateCubemap = false;
            }
        }
示例#8
0
    // This function computes a diffuse environment map in
    // "filteredCubemap" of the same dimensions as "originalCubemap"
    // by integrating -- for each texel of "filteredCubemap" --
    // the diffuse illumination from all texels of "originalCubemap"
    // for the surface normal vector corresponding to the direction
    // of each texel of "filteredCubemap".
    private Cubemap computeFilteredCubeMap()
    {
        Cubemap filteredCubeMap = new Cubemap(originalCubeMap.width,
                                              originalCubeMap.format, true);

        int filteredSize = filteredCubeMap.width;
        int originalSize = originalCubeMap.width;

        // Compute all texels of the diffuse environment cube map
        // by itterating over all of them
        for (int filteredFace = 0; filteredFace < 6; filteredFace++)
        // the six sides of the cube
        {
            for (int filteredI = 0; filteredI < filteredSize; filteredI++)
            {
                for (int filteredJ = 0; filteredJ < filteredSize; filteredJ++)
                {
                    Vector3 filteredDirection =
                        getDirection(filteredFace,
                                     filteredI, filteredJ, filteredSize).normalized;
                    float   totalWeight = 0.0f;
                    Vector3 originalDirection;
                    Vector3 originalFaceDirection;
                    float   weight;
                    Color   filteredColor = new Color(0.0f, 0.0f, 0.0f);

                    // sum (i.e. integrate) the diffuse illumination
                    // by all texels in the original environment map
                    for (int originalFace = 0; originalFace < 6; originalFace++)
                    {
                        originalFaceDirection = getDirection(
                            originalFace, 1, 1, 3).normalized;
                        //the normal vector of the face

                        for (int originalI = 0; originalI < originalSize; originalI++)
                        {
                            for (int originalJ = 0; originalJ < originalSize; originalJ++)
                            {
                                originalDirection = getDirection(
                                    originalFace, originalI,
                                    originalJ, originalSize);
                                // direction to the texel
                                // (i.e. light source)
                                weight = 1.0f
                                         / originalDirection.sqrMagnitude;
                                // take smaller size of more
                                // distant texels into account
                                originalDirection =
                                    originalDirection.normalized;
                                weight = weight * Vector3.Dot(
                                    originalFaceDirection,
                                    originalDirection);
                                // take tilt of texel compared
                                // to face into account
                                weight = weight * Mathf.Max(0.0f,
                                                            Vector3.Dot(filteredDirection,
                                                                        originalDirection));
                                // directional filter
                                // for diffuse illumination
                                totalWeight = totalWeight + weight;
                                // instead of analytically
                                // normalization, we just normalize
                                // to the potential max illumination
                                filteredColor = filteredColor + weight
                                                * originalCubeMap.GetPixel(
                                    (CubemapFace)originalFace,
                                    originalI, originalJ);   // add the
                                                             // illumination by this texel
                            }
                        }
                    }
                    filteredCubeMap.SetPixel(
                        (CubemapFace)filteredFace, filteredI,
                        filteredJ, filteredColor / totalWeight);
                    // store the diffuse illumination of this texel
                }
            }
        }

        // Avoid seams between cube faces: average edge texels
        // to the same color on each side of the seam
        int maxI = filteredCubeMap.width - 1;

        for (int i = 0; i < maxI; i++)
        {
            setFaceAverage(ref filteredCubeMap,
                           0, i, 0, 2, maxI, maxI - i);
            setFaceAverage(ref filteredCubeMap,
                           0, 0, i, 4, maxI, i);
            setFaceAverage(ref filteredCubeMap,
                           0, i, maxI, 3, maxI, i);
            setFaceAverage(ref filteredCubeMap,
                           0, maxI, i, 5, 0, i);

            setFaceAverage(ref filteredCubeMap,
                           1, i, 0, 2, 0, i);
            setFaceAverage(ref filteredCubeMap,
                           1, 0, i, 5, maxI, i);
            setFaceAverage(ref filteredCubeMap,
                           1, i, maxI, 3, 0, maxI - i);
            setFaceAverage(ref filteredCubeMap,
                           1, maxI, i, 4, 0, i);

            setFaceAverage(ref filteredCubeMap,
                           2, i, 0, 5, maxI - i, 0);
            setFaceAverage(ref filteredCubeMap,
                           2, i, maxI, 4, i, 0);
            setFaceAverage(ref filteredCubeMap,
                           3, i, 0, 4, i, maxI);
            setFaceAverage(ref filteredCubeMap,
                           3, i, maxI, 5, maxI - i, maxI);
        }

        // Avoid seams between cube faces:
        // average corner texels to the same color
        // on all three faces meeting in one corner
        setCornerAverage(ref filteredCubeMap,
                         0, 0, 0, 2, maxI, maxI, 4, maxI, 0);
        setCornerAverage(ref filteredCubeMap,
                         0, maxI, 0, 2, maxI, 0, 5, 0, 0);
        setCornerAverage(ref filteredCubeMap,
                         0, 0, maxI, 3, maxI, 0, 4, maxI, maxI);
        setCornerAverage(ref filteredCubeMap,
                         0, maxI, maxI, 3, maxI, maxI, 5, 0, maxI);
        setCornerAverage(ref filteredCubeMap,
                         1, 0, 0, 2, 0, 0, 5, maxI, 0);
        setCornerAverage(ref filteredCubeMap,
                         1, maxI, 0, 2, 0, maxI, 4, 0, 0);
        setCornerAverage(ref filteredCubeMap,
                         1, 0, maxI, 3, 0, maxI, 5, maxI, maxI);
        setCornerAverage(ref filteredCubeMap,
                         1, maxI, maxI, 3, 0, 0, 4, 0, maxI);

        filteredCubeMap.Apply(); //apply all SetPixel(..) commands

        return(filteredCubeMap);
    }
        public static Color GetColorInDirection(this Cubemap cubemap, Vector3 dir)
        {
            // this could be faster, save some of the calculations to be reused
            float       x   = 0;
            float       y   = 0;
            Ray         ray = new Ray(Vector3.zero, dir);
            float       d;
            Plane       p;
            Vector3     pos;
            CubemapFace face = CubemapUtils.GetFace(dir);

            switch (face)
            {
            case CubemapFace.PositiveX:
                p = new Plane(-Vector3.right, 1);
                p.Raycast(ray, out d);
                pos = ray.GetPoint(d);
                x   = -0.5f * pos.z + 0.5f;
                y   = -0.5f * pos.y + 0.5f;
                break;

            case CubemapFace.NegativeX:
                p = new Plane(Vector3.right, 1);
                p.Raycast(ray, out d);
                pos = ray.GetPoint(d);
                x   = 0.5f * pos.z + 0.5f;
                y   = -0.5f * pos.y + 0.5f;
                break;

            case CubemapFace.PositiveY:
                p = new Plane(-Vector3.up, 1);
                p.Raycast(ray, out d);
                pos = ray.GetPoint(d);
                x   = 0.5f * pos.x + 0.5f;
                y   = 0.5f * pos.z + 0.5f;
                break;

            case CubemapFace.NegativeY:
                p = new Plane(Vector3.up, 1);
                p.Raycast(ray, out d);
                pos = ray.GetPoint(d);
                x   = 0.5f * pos.x + 0.5f;
                y   = -0.5f * pos.z + 0.5f;
                break;

            case CubemapFace.PositiveZ:
                p = new Plane(-Vector3.forward, 1);
                p.Raycast(ray, out d);
                pos = ray.GetPoint(d);
                x   = 0.5f * pos.x + 0.5f;
                y   = -0.5f * pos.y + 0.5f;
                break;

            case CubemapFace.NegativeZ:
                p = new Plane(Vector3.forward, 1);
                p.Raycast(ray, out d);
                pos = ray.GetPoint(d);
                x   = -0.5f * pos.x + 0.5f;
                y   = -0.5f * pos.y + 0.5f;
                break;
            }
            return(cubemap.GetPixel(face, (int)(x * cubemap.width), (int)(y * cubemap.height)));
        }