- Home /
Create a texture with cylindrical mapping from script
Hi,
By advance, sorry if my question sounds silly, I've only started learning Unity recently.
I want to display 360° images. Currently, I've done it in Unity editor with success, and my problem is now to load images at runtime (from a local or a remote image file).
To display them, I added a skybox to the main camera. It's material use the "Skybox/Cubemap" shader, and the texture in this material use a "Latitude-Longitude layout (cylindrical).
I've found how to access in C# the material (Camera.main.GetComponent ().material), and I saw that the texture is referenced as "_Cube" (Camera.main.GetComponent ().material.GetTexture ("_Tex")), and is apparently a Cubemap.
Now, I would like to change this texture, and so I want to create a new Cubemap, and load it with an image file, using the same cylindrical mapping.
On a Cubemap, I can only set pixels for 6 faces, so I think that the editor as an algorithm to convert cylindrical coordinates to cube coordinates.
Do you know if this algorithm is available somewhere in C# Unity libs ?
As anyone a more clever way to dynamically load images for skyboxes ? (maybe converting Texture2D to Cubemap, ....)
Shame that nobody replied to this, I've got the same problem myself.
Answer by Seb1101 · Nov 29, 2018 at 04:20 PM
Hi,
I solved this problem today if anyone is still interested. It may surely not be the best solution but at least it works.
Here's my script (It is attached to a button in order to change the skybox on click):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Crosstales.FB;
using UnityEditor;
using System.IO;
public class Import360 : MonoBehaviour {
private Texture2D importedSkybox;
public Material modulableSkyboxMat;
private string directory;
// Use this for initialization
void Start () {
directory = "";
modulableSkyboxMat.shader = Shader.Find("SkyboxPlus/Cubemap");
}
// Update is called once per frame
void Update () {
}
private IEnumerator LoadImages()
{
//Download Link
directory = FileBrowser.OpenSingleFile("Select a 360 TEXTURE file", System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop), "jpg");
Debug.Log(directory);
if (directory != "")
{
WWW www = new WWW(directory);
//Wait for the download to complete
yield return www;
importedSkybox = www.texture;
//Create path in the asset folders:
string path = "Assets/Resources/SVLevels/av26.jpg";
//Load Image to modify in the ressource folder
Texture2D tex2d = Resources.Load<Texture2D>("SVLevels/av26");
//Uptake byte data from downloaded www image
byte[] imData = importedSkybox.EncodeToJPG();
File.WriteAllBytes(Application.dataPath + "/Resources/SVLevels/av26.jpg", imData);
//Change the texture to cubemap:
TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path);
if (tex2d != null && tex2d.dimension != UnityEngine.Rendering.TextureDimension.Cube)
{
importer.textureShape = TextureImporterShape.TextureCube;
importer.SaveAndReimport();
}
// yield return new WaitForSecondsRealtime(1); //INCREASE OR DECREASE THIS TIMING; Depends on the ability of the computer to rapidly execute the previous tasks
//Reference the Skybox material with the newly made cubemap texture ! IT WILL BE A CUBEMAP TO LOAD AGAIN!
Cubemap finalSkybox = Resources.Load<Cubemap>("SVLevels/av26");
modulableSkyboxMat.mainTexture = finalSkybox;
RenderSettings.skybox = modulableSkyboxMat;
}
}
public void OnClickChangeEnvironment()
{
Cubemap cube2d = Resources.Load<Cubemap>("SVLevels/av26");
string path = "Assets/Resources/SVLevels/av26.jpg";
TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path);
if (cube2d != null && cube2d.dimension == UnityEngine.Rendering.TextureDimension.Cube)
{
importer.textureShape = TextureImporterShape.Texture2D;
importer.SaveAndReimport();
}
StartCoroutine("LoadImages");
}
}
For this script to work you will need 2 things in your Asset Folder:
A Texture2D that will be updated when uploading a new www.texture (in my case it is av26.jpg)
A material that will be set to Skybox/Cubemap and will take the newly uploaded texture as input after the latter has been changed to cubemap (in my case: modulableSkyboxMat)
Both elements were placed in a folder in the Asset folder. (in my case: Assets/Resources/SVLevels)
Hope this helps others! :)
Thank you so much!! it works perfectly! but plz when I build it to android platform! it doesn't work! any help please! I try to build it into an android application and installed in my phone when I click on the button nothing happing thought it work perfectly on unity editor.
Your answer
Follow this Question
Related Questions
Scripting Help with My Projectile System 1 Answer
Add Light Source to Sun in Environmental Lighting with Unity 5 by Script? 3 Answers
Creating Material from String (Unity 5.6) 1 Answer
How to Create Cube Skybox Texture 2 Answers
Why are changes to scene's Skybox.material NOT reset when play mode over? 1 Answer