After changing a material's main texture, the main texture is null

I’m trying to load a jpeg image from disk and set it as the skybox’s material. I retrieve the image from disk, then use texture.LoadImage() to add the image to the texture. I create a new material, and set the texture (which exists and is not null) to the new material mate.mainTexture. After setting the texture to the material the skybox turns grey. After some debugging, I determined that is caused by mat.mainTexture remaining null and not being set to the texture.

Here is the code that creates and sets the material:

Debug.Log("Checking if image exists");
string fileName = name + "-" + id.ToString ();
string filePath = "";
if (Application.platform == RuntimePlatform.Android) {
        filePath = Application.persistentDataPath + "/Resources/skyboxImages/" + fileName + ".jpg";
} else {
        filePath = Application.persistentDataPath + "/Resources/skyboxImages/" + fileName + ".jpg";
}

Debug.Log ("Checking: " + filePath);

if (!File.Exists (filePath)) {
        Debug.Log("File does not exist");
        return null;
}

byte[] fileData = File.ReadAllBytes (filePath);

Debug.Log("Creating material");
Material mat = new Material(Shader.Find("Skybox/Cubemap"));
Debug.Log ("Created material: " + mat + " END");

Debug.Log ("Creating texture");
Texture2D texture = new Texture2D (2048, 2048, TextureFormat.PVRTC_RGB4, false);
Debug.Log ("Created texture: " + texture);

Debug.Log ("Setting name: " + name);
texture.name = name;

Debug.Log ("Loading image into texture.");

bool loadImageSuccess = texture.LoadImage (fileData);
Debug.Log ("Success: " + loadImageSuccess.ToString() + " Texture size: {" + texture.width.ToString () + ", " + texture.height.ToString () + "}");

mat.mainTexture = texture;

Debug.Log ("This (" + texture + ") should equal this (" + mat.mainTexture + ")");
print ("Setting skybox.");
RenderSettings.skybox = mat;
DynamicGI.UpdateEnvironment ();

print ("Skybox: " + RenderSettings.skybox + " Textute: " + RenderSettings.skybox.mainTexture);

And this is the debug log:

Checking if image exists
Checking: /var/mobile/Containers/Data/Application/1B02811B-B2C3-44DD-BE35-C0509E50CC7F/Documents/Resources/skyboxImages/Office-2.jpg
Creating material
Created material: Skybox/Cubemap (UnityEngine.Material) END
Creating texture
Created texture:  (UnityEngine.Texture2D)
Setting name: Office
Loading image into texture.
This (Office (UnityEngine.Texture2D)) should equal this ()
Setting skybox.
Skybox: Skybox/Cubemap (UnityEngine.Material) Textute: 
SkyboxLogic:RetreivedSkyboxList()

Why is the texture not being set to the material?

Attempts:

  • I have tried using the png data in the Unity example here. And I get the same result. (Dark grey skybox, mat.mainTexture is null.
  • I have tried using: mat.setTexture("_MainTex", texture); to set the texture instead of mat.mainTexture = texture and I get the same result of mat.mainTexture is null and a grey skybox.
  • I have also tried not creating the new material and setting the texture of the directly to Renderer.skybox.mainTexture. This produces no change in the skybox. It remains the previous material.

UPDATE

I have updated the code to create cube maps as @FortisVenaliter suggested and am receiving an error when trying to set the texture to on of the cube map’s faces:
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats
The part I don’t understand is that the imported texture’s format is RGB24.

It also looks like the material is still not accepting the cube map.

The updated code:

string[] imageList = new string[6] {"posx.jpg", "negx.jpg", "posy.jpg", "negy.jpg", "posz.jpg", "negz.jpg"};
CubemapFace[] faceList = new CubemapFace[6] {CubemapFace.PositiveX, CubemapFace.NegativeX, CubemapFace.PositiveY, CubemapFace.NegativeY, CubemapFace.PositiveZ, CubemapFace.NegativeZ};

Cubemap cubemap = new Cubemap (2048, TextureFormat.PVRTC_RGB4, false);

for (int i = 0; i < 6; i++) {
        string imageName = imageList *;*

CubemapFace face = faceList ;

Debug.Log(“Checking if image exists”);
string filePath = “”;
if (Application.platform == RuntimePlatform.Android) {
filePath = Application.persistentDataPath + “/Resources/skyboxImages/” + id.ToString() + “/” + imageName;
} else {
filePath = Application.persistentDataPath + “/Resources/skyboxImages/” + id.ToString() + “/” + imageName;
}

Debug.Log ("Checking: " + filePath);

if (!File.Exists (filePath)) {
Debug.Log(“File does not exist”);
return null;
}

byte[] fileData = File.ReadAllBytes (filePath);

Debug.Log (“Creating texture”);
Texture2D texture = new Texture2D (2048, 2048, TextureFormat.RGB24, false);
Debug.Log ("Created texture: " + texture);

Debug.Log (“Loading image into texture.”);
bool loadImageSuccess = texture.LoadImage (fileData);
fileData = null;
Debug.Log (“Success: " + loadImageSuccess.ToString() + " Texture size: {” + texture.width.ToString () + ", " + texture.height.ToString () + "} format: " + texture.format);

Debug.Log (“Setting image to cubemap.”);
cubemap.SetPixels(texture.GetPixels(), face);
cubemap.Apply ();
texture = null;
}

Resources.UnloadUnusedAssets ();

Debug.Log(“Creating material”);
Material mat = new Material(Shader.Find(“Skybox/Cubemap”));
Debug.Log (“Created material: " + mat + " END”);

mat.mainTexture = cubemap;

Debug.Log (“This (” + cubemap + “) should equal this (” + mat.mainTexture + “)”);
print (“Setting skybox.”);
RenderSettings.skybox = mat;
DynamicGI.UpdateEnvironment ();

print ("Skybox: " + RenderSettings.skybox + " Textute: " + RenderSettings.skybox.mainTexture)

And here is the updated debug log:
Checking if image exists
Checking: /var/mobile/Containers/Data/Application/8458AAEA-C977-4512-A220-B98913F65C19/Documents/Resources/skyboxImages/2/posx.jpg
Creating texture
Created texture: (UnityEngine.Texture2D)
Loading image into texture.
Success: True Texture size: {2048, 2048} format: RGB24
Setting image to cubemap.
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats

Checking if image exists
Checking: /var/mobile/Containers/Data/Application/8458AAEA-C977-4512-A220-B98913F65C19/Documents/Resources/skyboxImages/2/negx.jpg
Unloading 5 Unused Serialized files (Serialized files now loaded: 0)
Loading image into texture.
Success: True Texture size: {2048, 2048} format: RGB24
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats

Checking if image exists
Checking: /var/mobile/Containers/Data/Application/8458AAEA-C977-4512-A220-B98913F65C19/Documents/Resources/skyboxImages/2/posy.jpg
Creating texture
Created texture: (UnityEngine.Texture2D)
Loading image into texture.
Success: True Texture size: {2048, 2048} format: RGB24
Setting image to cubemap.
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats

Checking if image exists
Checking: /var/mobile/Containers/Data/Application/8458AAEA-C977-4512-A220-B98913F65C19/Documents/Resources/skyboxImages/2/negy.jpg
Creating texture
Created texture: (UnityEngine.Texture2D)
Loading image into texture.
Success: True Texture size: {2048, 2048} format: RGB24
Setting image to cubemap.
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats

Checking if image exists
Checking: /var/mobile/Containers/Data/Application/8458AAEA-C977-4512-A220-B98913F65C19/Documents/Resources/skyboxImages/2/posz.jpg
Creating texture
Created texture: (UnityEngine.Texture2D)
Loading image into texture.
Success: True Texture size: {2048, 2048} format: RGB24
Setting image to cubemap.
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats

Checking if image exists
Checking: /var/mobile/Containers/Data/Application/8458AAEA-C977-4512-A220-B98913F65C19/Documents/Resources/skyboxImages/2/negz.jpg
Creating texture
Created texture: (UnityEngine.Texture2D)
Success: True Texture size: {2048, 2048} format: RGB24
Setting image to cubemap.
Unsupported texture format - needs to be ARGB32, RGBA32, RGB24, Alpha8 or one of float formats

Creating material
Created material: Skybox/Cubemap (UnityEngine.Material) END
This ( (UnityEngine.Cubemap)) should equal this ()

Setting skybox.
Skybox: Skybox/Cubemap (UnityEngine.Material) Textute:

Unloading 13 unused Assets to reduce memory usage. Loaded Objects now: 260.
Total: 64.804794 ms (FindLiveObjects: 0.077833 ms CreateObjectMapping: 0.016750 ms MarkObjects: 7.544916 ms DeleteObjects: 56.372875 ms)
UPDATE 2
--------------
I figured out from trial and error, that the skybox texture is set to the material’s _Tex texture. Replacing mat.mainTexture = cubemap; above to mat.SetTexture("_Tex", cubemap); The skybox turns pink when the material is changed.

Doesn’t the Skybox\Cubemap shader require a TextureCube instead of a Texture2D? If you set the wrong type, it will reject the value.