I’m creating a mesh at runtime and want to add a jpg file that’s on the HDD and that I’m reading at runtime as a texture. Changing the color works but other than that mesh stays white and won’t display the texture.
I checked, it does actually find and read the file and I can get the dimensions with “tex.width” and “tex.height”.
The UVs are set in my code, isn’t that enough to have the mesh show its texture?
My code (Unity 2017.3.1f1):
private GameObject MakePlane(String path,float length, float width) {
if(File.Exists(path)) {
GameObject o = new GameObject();
Texture2D tex;
byte[] fileData;
fileData = File.ReadAllBytes(path);
tex = new Texture2D(2,2);
tex.LoadImage(fileData);
Mesh m = new Mesh();
Material mat = new Material(Shader.Find("Hidden/Internal-Colored"));
mat.mainTexture = tex;
o.AddComponent<MeshFilter>();
o.AddComponent<MeshRenderer>();
o.GetComponent<MeshFilter>().mesh = m;
o.GetComponent<MeshRenderer>().material = mat;
m.vertices = new Vector3[] { new Vector3(0,0,0),new Vector3(length,0,0),new Vector3(length,width,0),new Vector3(0,width,0) };
m.uv = new Vector2[] {new Vector2(0,0),new Vector2(0,1),new Vector2(1,1),new Vector2(1,0)};
m.triangles = new int[] { 0,1,2,0,2,3 };
m.RecalculateBounds();
m.RecalculateNormals();
return o;
}
}
Oh, thanks!
Which one could I use instead? With the standard one (“Shader.Find(“Standard”)”) the mesh doesn’t even show up. My scene uses only the single, default Directional Light and the default Main Camera.
I think the easiest way would be to setup a material in the editor and just use it from your code.
Otherwise I’d suggest writing your own shader that has only the things you need.
I can’t pre-import the images because they are indirectly chosen at runtime by the player, same with the size and location (didn’t include that part in my first post) of the plane, so I have to load them and texture the plane at runtime.
Is there no other shader I can use instead? I have no idea how to write my own and honestly, I also don’t have the background knowledge about what to use either (yes, I did see the “A Gentle Introduction to Shaders” tutorial).
Edit:
Is there a reason why the standard shader doesn’t display anything at all? Additional to the vertices I set the triangles and the UVs and let it calculate the normals, shouldn’t that be enough to make it work?
Like @aleksandrk said, you can use a pre-made material. You don’t need to assign a texture to it in the editor, just reference an “empy” material in you script, and assign the texture from there.
public Material material; // This will be displayed in the inspector
void MakePlane(...)
{
...
Material mat = Instanciate(material); // will create a copy of the referenced material
...
}
Sorry but I don’t understand how that would change anything. Isn’t creating a new material through the GUI with the default settings (as I don’t need “metallic”, “normal map” or “height map” - don’t know what “Albedo” is) and the standard shader basically:
Material mat = new Material(Shader.Find("Standard"));
The only difference is that I can’t make clones because my “mat” isn’t a prefab (like your “material”) but since there’s only one textured plane in my scene at any time, that doesn’t matter anyway.
The problem is that my plane isn’t displayed with the standard shader (so ‘Shader.Find(“Standard”)’), even though I should have set everything the mesh needs, and I don’t know which shader will make both the mesh and the texture show up.
Plus, I can’t access my script in the inspector because it isn’t connected to a game object. I have a static class to share data between scripts and this static class also creates an instance of the class the “MakePlane” method is in, which inherits from ScriptableObject (to stop the complaining about creating a new MonoBehaviour).
Ok, I’ve tested, it should work.
But could it be that the triangles of your plane are drawn in the wrong order, resulting in faces beeing inverted ?
The Internal-Colored shader doesn’t do any face culling by default, while the standard one culls back faces.
This could explain why you see something with the first one but nothing with standard, with the same point of view.
It works for you with a prefab (default settings and shader) and my code?
I just checked with the standard shader: There is indeed a huge, black plane if you look from below but it’s missing its texture, so it might really be a problem with the UVs.
Are there any shaders that you can use textures with but also let you disable backface culling?
It worked with the quad primitive.
I tried your code and it worked too.
The plane may be black because it’s not lit ? If it’s not facing the directional light and there’s not ambiant lighting, this is also totally normal.
If you want to be sure you can try to use the “Unlit/Texture” shader.
Not built-in.
You could still duplicate one of the existing shaders and disable the backface culling.
Or double the vertices of you mesh and invert the triangle for thoses.
Ah, okay.
This might be a stupid question: Won’t doubling the vertices create these “glitching” textures or do you not get anything like that if the normals point the opposite way?
If doubling the vertices AND inversing the new triangles, then if you display your object with a backface culling material, then only the triangles with the normal pointing toward the camera will be displayed.
But if you display it with a material that doesn’t do face culling, then yes, you will have polygon overlap.