- Home /
INDECIPHERABLE rendering order problem when modifying material property on Runtime
I want to change the material of an object at runtime. This material will use the shader “Transparent/VertexLit”. There are two different scenarios where this happens, on the first one the material will be assign without modifying any of its properties. On the second one, only of its properties is modified (“_Color”).
Next you’ll find the first case scenario. The new material is assigned through the editor to the variable transparentMaterial and then assigned to the renderer.material:
newMat = new Material(transparentMaterial);
newMat.CopyPropertiesFromMaterial(transparentMaterial);
renderer.material = newMat;
The previous code, renders the following results:
As you may see on each image the result is the same, meaning, full transparency on each object.
For the second case, the code is the following:
newMat = new Material(transparentMaterial);
newMat.CopyPropertiesFromMaterial(transparentMaterial);
newMat.SetColor("_Color", Color.red);
renderer.material = newMat;
As you may see, there’s only one line that changes but the result is dramatically different from the previous one. Next are the results:
On the previous images, you can appreciate a only partial transparency. Let’s recall that the material is exactly the same on each case, but when you tried to modify a property of the material (in this case “_Color”) the results are awful. As you may see, on the left image, the middle stick is not transparent, even though it’s supposed to be. On the middle image you can appreciate full transparency only on the one of the vertical sticks, but the middle one still doesn’t show any transparency. On the image of the right, on the “3” side, you can’t see the object that is behind that part of the stick, but on the “3’ ” side, you are able to see the object behind.
When I was debugging this scenario, I realized that the order of the objects in which I changed the material would affect the transparencies. For example, if I only change the material of one stick (object), then I won’t be able to see anything through it. If after doing that I change the material of a second stick, I will be able to see through I will only see the first object which its material was changed. Through the second objects transparency I won’t be able to see the third stick. Add to that, when looking from the first one you still won’t see through it, even the one which its material just changed. When you change the material of the third object, the exact same thing happens. When you look through it, you’ll be able to see the first and second objects. When you look though the second one, you’ll only be able to see the first one (even though not the third one is now supposed to be transparent it does not appears behind the second one). When looking through the first one, you won’t be able to see anything behind it.
The previous description is the explanation of why only some objects look transparent on the second group of images. I’ve exhausted every resource I had to solve this, so now I’m hoping to solve this with your help. Thanks in advance.
Best regards,
Sebastián
Come on guys! This must be something really easy for all the pros!
Answer by Loius · Oct 18, 2013 at 04:32 PM
You're setting the color to .Red, which is (1,0,0,1). The fourth argument is alpha (transparency); you want that at less-than-one.
You could do "newMat.SetColor("_Color", new Color(1f,0f,0f,0.5f));", or you could be amazing with extension methods which has saved me so much time:
// goes in any subdirectory of the Plugins folder
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditorInternal;
#endif
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public static class UtilityExtensions {
#region Color
public static Color WithR(this Color c, float r) {return new Color(r,c.g,c.b,c.a);}
public static Color WithG(this Color c, float g) {return new Color(c.r,g,c.b,c.a);}
public static Color WithB(this Color c, float b) {return new Color(c.r,c.g,b,c.a);}
public static Color WithA(this Color c, float a) {return new Color(c.r,c.g,c.b,a);}
#endregion
}
With that in place you can "newMat.SetColor("_Color", Color.red.WithA(0.5f));"
You were right. That was my problem. The only line I had to change was on the inicialization. And that was all. Thanks a lot. private void Start() {
Color transpColorAlpa = transparent$$anonymous$$aterial.GetColor("_Color");
selectedColor = new Color(1,0,0,transpColorAlpa.a);
}