2017-07-11 14 views
4

サーバから画像をダウンロードし、それをCubemapで変換し、最後にこのCubeMapをSkyboxに入れる必要があります。リモート画像からCubemap Skyboxを編集する

私はC#で動作します。

私はこのコードを思い付いた:

public string url = "image/url.jpg"; 

void Update() { 
    // When trigger, we start the process 
    if (Input.GetKeyDown("f")) { 

     // start Coroutine to handle the WWW asynchronous process 
     StartCoroutine("setImage"); 
    } 
} 

IEnumerator setImage() { 

    Texture2D tex; 
    tex = new Texture2D(2048, 2048, TextureFormat.RGBA32, false); 

    WWW www = new WWW(url); 
    //Texture myGUITexture = Resources.Load("23") as Texture; 

    Debug.Log (www.bytesDownloaded); 
    Debug.Log (www.progress); 
    Debug.Log (www.texture); 

    yield return www; 

    // we put the downloaded image into the new texture 
    www.LoadImageIntoTexture(tex); 

    // new cubemap 
    Cubemap c = new Cubemap(2048, TextureFormat.RGBA32, false); 
    Color[] CubeMapColors; 
    CubeMapColors = tex.GetPixels(); 
    c.SetPixels(CubeMapColors, CubemapFace.PositiveX); 
    // we set the cubemap from the texture pixel by pixel 
    c.Apply(); 

    //NewTexture.isPowerOfTwo = true; 

    //Debug.Log (RenderSettings.skybox.GetTexture ("_Tex")); 

    // We change the Cubemap of the Skybox 
    RenderSettings.skybox.SetTexture("_Tex", c); 
} 

私は私がやっていると思うかを説明するために、すべてのコードをコメントしました。

私は、編集者の方法(それは信じられないほど簡単です)が私が読むことができる他の人の投稿からは不可能であると思われるので、ピクセルごとにCubemapを作成するという "トリック"を作りました。

最終的に、結果は単なるグレーのピクセルの束でした。

私のプロセスで何が酷くなっているのか分かりませんが、唯一の「影」のポイントはTextureFormatです。

Unity Editorを見ると、SetTextureでは不可能と記録されているエラーであるBC7形式が表示され、docから、RGBA32で圧縮解除される可能性があることが説明されています。

もちろん、コンソールに残りのエラーはありません。

私は本当に簡単な方法がないことに驚いています。私は必ずしもhttpの画像からスカイボックスに入れているわけではありませんが、スカイボックスのテクスチャを変更するだけです。何か不足していますか?

+1

キューブマップは6面あります。あなたはそれらの6つすべてを設定するはずですが、コード内に 'CubemapFace.PositiveX'を1つだけ設定しています。 – Programmer

+0

しかし、私は6部で画像を分割するにはどうすればいいですか?実際に私はUnity Editorがその材料に対してCubemapの特性を設定したときにUnity Editorがそれを行っていたことを読みましたが、C#スクリプトでこれを行う例は見つかりませんでした。 – Alburkerk

+1

6面すべてに同じ画像を配置しようとしていますか?または画像を展開しますか? – user1767754

答えて

1

解決策が見つかりました。

次のコードは、基本的にコードの拡張です。

私は気になるものを修正しましたが、コードは基本的に同じです。 、

  • は、それぞれの顔についてwww
  • からパノラマのテクスチャを取得
  • 収集キューブマップに生成されたテクスチャを割り当てるテクスチャを計算します。

    using System.Collections; 
    using UnityEngine; 
    
    public class ReplaceCubemap : MonoBehaviour 
    { 
        public string url = "your file name"; 
        public int CubemapResolution = 256; 
    
        private Texture2D source; 
    
        /// <summary> 
        /// These are the faces of a cube 
        /// </summary> 
        private Vector3[][] faces = 
        { 
         new Vector3[] { 
          new Vector3(1.0f, 1.0f, -1.0f), 
          new Vector3(1.0f, 1.0f, 1.0f), 
          new Vector3(1.0f, -1.0f, -1.0f), 
          new Vector3(1.0f, -1.0f, 1.0f) 
         }, 
         new Vector3[] { 
          new Vector3(-1.0f, 1.0f, 1.0f), 
          new Vector3(-1.0f, 1.0f, -1.0f), 
          new Vector3(-1.0f, -1.0f, 1.0f), 
          new Vector3(-1.0f, -1.0f, -1.0f) 
         }, 
         new Vector3[] { 
          new Vector3(-1.0f, 1.0f, 1.0f), 
          new Vector3(1.0f, 1.0f, 1.0f), 
          new Vector3(-1.0f, 1.0f, -1.0f), 
          new Vector3(1.0f, 1.0f, -1.0f) 
         }, 
         new Vector3[] { 
          new Vector3(-1.0f, -1.0f, -1.0f), 
          new Vector3(1.0f, -1.0f, -1.0f), 
          new Vector3(-1.0f, -1.0f, 1.0f), 
          new Vector3(1.0f, -1.0f, 1.0f) 
         }, 
         new Vector3[] { 
          new Vector3(-1.0f, 1.0f, -1.0f), 
          new Vector3(1.0f, 1.0f, -1.0f), 
          new Vector3(-1.0f, -1.0f, -1.0f), 
          new Vector3(1.0f, -1.0f, -1.0f) 
         }, 
         new Vector3[] { 
          new Vector3(1.0f, 1.0f, 1.0f), 
          new Vector3(-1.0f, 1.0f, 1.0f), 
          new Vector3(1.0f, -1.0f, 1.0f), 
          new Vector3(-1.0f, -1.0f, 1.0f) 
         } 
        }; 
    
        void Update() 
        { 
         // When trigger, we start the process 
         if (Input.GetKeyDown(KeyCode.F)) 
         { 
    
          // start Coroutine to handle the WWW asynchronous process 
          StartCoroutine(setImage()); 
         } 
        } 
    
        IEnumerator setImage() 
        { 
         WWW www = new WWW(url); 
         //Texture myGUITexture = Resources.Load("23") as Texture; 
    
         Debug.Log(www.bytesDownloaded); 
         Debug.Log(www.progress); 
         Debug.Log(www.texture); 
    
         yield return www; 
    
         source = new Texture2D(www.texture.width, www.texture.height); 
         // we put the downloaded image into the new texture 
         www.LoadImageIntoTexture(source); 
    
         // new cubemap 
         Cubemap c = new Cubemap(CubemapResolution, TextureFormat.RGBA32, false); 
    
         Color[] CubeMapColors; 
    
         for (int i = 0; i < 6; i++) 
         { 
          CubeMapColors = CreateCubemapTexture(CubemapResolution, (CubemapFace)i); 
          c.SetPixels(CubeMapColors, (CubemapFace)i); 
         } 
         // we set the cubemap from the texture pixel by pixel 
         c.Apply(); 
    
         //Destroy all unused textures 
         DestroyImmediate(source); 
         DestroyImmediate(www.texture); 
         Texture2D[] texs = FindObjectsOfType<Texture2D>(); 
         for (int i = 0; i < texs.Length; i++) 
         { 
          DestroyImmediate(texs[i]); 
         } 
    
         // We change the Cubemap of the Skybox 
         RenderSettings.skybox.SetTexture("_Tex", c); 
        } 
    
        /// <summary> 
        /// Generates a Texture that represents the given face for the cubemap. 
        /// </summary> 
        /// <param name="resolution">The targetresolution in pixels</param> 
        /// <param name="face">The target face</param> 
        /// <returns></returns> 
        private Color[] CreateCubemapTexture(int resolution, CubemapFace face) 
        { 
         Texture2D texture = new Texture2D(resolution, resolution, TextureFormat.RGB24, false); 
    
         Vector3 texelX_Step = (faces[(int)face][1] - faces[(int)face][0])/resolution; 
         Vector3 texelY_Step = (faces[(int)face][3] - faces[(int)face][2])/resolution; 
    
         float texelSize = 1.0f/resolution; 
         float texelIndex = 0.0f; 
    
         //Create textured face 
         Color[] cols = new Color[resolution]; 
         for (int y = 0; y < resolution; y++) 
         { 
          Vector3 texelX = faces[(int)face][0]; 
          Vector3 texelY = faces[(int)face][2]; 
          for (int x = 0; x < resolution; x++) 
          { 
           cols[x] = Project(Vector3.Lerp(texelX, texelY, texelIndex).normalized); 
           texelX += texelX_Step; 
           texelY += texelY_Step; 
          } 
          texture.SetPixels(0, y, resolution, 1, cols); 
          texelIndex += texelSize; 
         } 
         texture.wrapMode = TextureWrapMode.Clamp; 
         texture.Apply(); 
    
         Color[] colors = texture.GetPixels(); 
         DestroyImmediate(texture); 
    
         return colors; 
        } 
    
        /// <summary> 
        /// Projects a directional vector to the texture using spherical mapping 
        /// </summary> 
        /// <param name="direction">The direction in which you view</param> 
        /// <returns></returns> 
        private Color Project(Vector3 direction) 
        { 
         float theta = Mathf.Atan2(direction.z, direction.x) + Mathf.PI/180.0f; 
         float phi = Mathf.Acos(direction.y); 
    
         int texelX = (int)(((theta/Mathf.PI) * 0.5f + 0.5f) * source.width); 
         if (texelX < 0) texelX = 0; 
         if (texelX >= source.width) texelX = source.width - 1; 
         int texelY = (int)((phi/Mathf.PI) * source.height); 
         if (texelY < 0) texelY = 0; 
         if (texelY >= source.height) texelY = source.height - 1; 
    
         return source.GetPixel(texelX, source.height - texelY - 1); 
        } 
    } 
    

    何のコードは基本的にないことですガベージ

  • キューブマップをシェーダに割り当てます