- Home /
Procedurally Generated Mesh Texture problem
Hi,
I procedurally created a mesh as stated in the tutorial http://docs.unity3d.com/Documentation/Manual/GeneratingMeshGeometryProcedurally.html
This mesh has a strange model. It is created to put a render-to-texture on it, so that it get's that shape. The mesh data is created by a calibration tool, which has been tested and works correctly. So now I'm integrating it with Unity.
I load the Vertices, the UV-coordinates (for the textures) and give the triangles. All of that should be correct.
However, in that tutorial is no where stated what to do with that script once you created it. So what I did was, create a plane from gameObjects in the unity menu, and I added the script. The mesh is loaded correctly, however I have trouble placing the texture.
I never got to see the texture at first, but once I used WWW I managed to load it, however the texture is being tiled instead of stretched. You can see it below. Is this happening because of the default material and shader values of the plane? Though I have to mention that this mesh consists out of over 6000 vertices. All with correct uv coordinates, and the triangles are also correctly set with calculating the normals of every vertex. So what am I doing wrong here any helps? (below the code I use to generate this mesh.)
By the way, I'm using that mesh as test only to see if I get the correct shape. I actually have to load a rendertotexture. I have one created out of a secondary camera, which is now available on my assets. Do you guys also now How I can set it through the script?
This is urgent, I'd be happy if I can get an answer quickly.

Code: (don't mind the many commented lines, I was trying different was to make this work)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System;
public class NewBehaviourScript : MonoBehaviour {
/*
* This is the script for dynamically loading the mesh that will
* contain the render to texture.
* (for now only one mesh will be laoded. 2 more will be added later if necessary)
*/
//Flag indicating if the mesh is loaded or not (prevents loading multiple times)
bool meshLoaded = false;
//vertices of the mesh
List<Vector3> vertexList = new List<Vector3>();
//triangles of the mesh
List<int> triangleList = new List<int>();
// uv coordinates of the mesh
List<Vector2> uvList = new List<Vector2>();
Mesh mpMesh;
Material mat;
// Use this for initialization
IEnumerator Start()
{
meshLoaded = true;
//string filePath = "C:\\Users\\ISA\\Desktop\\testMesh.txt";
//string texturePath = "C:\\Users\\ISA\\Desktop\\gridTexture.jpg";
string filePath = "Assets\\Resources\\MultiprojectorMesh0.txt";
string texturePath = "file:C:/Users/ISA/Documents/School_Documenten/2012-2013/Bachelorproef/Coding/First/Assets/ketnet.png";
WWW www = new WWW(texturePath);
yield return www;
mat = new Material(Shader.Find("Self-Illumin/VertexLit"));
//mat.color = new Color(0, 1, 0);
//mat.mainTexture = (Texture2D)Resources.Load(texturePath);
www.texture.wrapMode = TextureWrapMode.Clamp;
mat.mainTexture = www.texture;
//mat.SetTexture("_MainTex", (Texture2D)Resources.Load(texturePath
//Loading Mesh
if (!readData(filePath))
{
meshLoaded = false;
Debug.Log("Error: Failed to create mesh.\n");
}
else
Debug.Log("Mesh successfully loaded.\n");
//Creating Mesh
if (meshLoaded)
{
MeshFilter mf = GetComponent<MeshFilter>();
mpMesh = new Mesh();
mf.mesh = mpMesh;
mpMesh.vertices = vertexList.ToArray();
mpMesh.triangles = triangleList.ToArray();
mpMesh.uv = uvList.ToArray();
mpMesh.RecalculateNormals();
//if (File.Exists(texturePath))
//{
// //renderer.material.mainTexture = (Texture2D)Resources.Load(texturePath);
// renderer.material.mainTexture = www.texture;
//}
//else
// Debug.Log("Error: Texture file " + texturePath + " not found!.\n");
//renderer.material.color = Color.red; //for example
}
}
// Update is called once per frame
void Update ()
{
if (meshLoaded)
Graphics.DrawMesh(mpMesh, transform.localToWorldMatrix, mat, 0);
}
//Reads the mesh data from the file
bool readData(string filePath)
{
string line;
bool vertices = false;
bool triangles = false;
bool success = true;
if (File.Exists(filePath))
{
StreamReader file = null;
try
{
file = new StreamReader(filePath);
while ((line = file.ReadLine()) != null)
{
if (line.Equals("VERT_XY_UV") && (line = file.ReadLine()) != null)
{
vertices = true;
triangles = false;
}
else if (line.Equals("TRI_XXX") && (line = file.ReadLine()) != null)
{
vertices = false;
triangles = true;
}
if (vertices)
parseVertex(line);
else if (triangles)
parseTriangle(line);
}
}
finally
{
//Closing stream
if (file != null)
file.Close();
}
}
else
{
Debug.Log("Error: The file" + filePath + " does not exist");
success = false;
}
return success;
}
//Parses the given line from the file stream
void parseVertex(string line)
{
// Prototype function, needs to be updated when I get legit values
int x, y;
// xxxx yyyy vertices
// zzzz not added because it's a 2d mesh, z is constant
x = Convert.ToInt32(line.Substring(0, 4));
y = Convert.ToInt32(line.Substring(5, 4));
vertexList.Add(new Vector3(x, y, 0));
//xxxx yyyy uv-coordinates
x = Convert.ToInt32(line.Substring(10, 4));
y = Convert.ToInt32(line.Substring(15, 4));
uvList.Add(new Vector2(x, y));
}
void parseTriangle(string line)
{
// xxx xxx xxx
int triangleP1 = Convert.ToInt32(line.Substring(0, 4));
int triangleP2 = Convert.ToInt32(line.Substring(5, 4));
int triangleP3 = Convert.ToInt32(line.Substring(10, 4));
Vector3 p1 = vertexList[triangleP1];
Vector3 p2 = vertexList[triangleP2];
Vector3 p3 = vertexList[triangleP3];
Vector3 U, V, normal;
U.x = p2.x - p1.x;
U.y = p2.y - p1.y;
U.z = p2.z - p1.z;
V.x = p3.x - p1.x;
V.y = p3.y - p1.y;
V.z = p3.z - p1.z;
normal.x = (U.y * V.z) - (U.z * V.y);
normal.y = (U.z * V.x) - (U.x * V.z);
normal.z = (U.x * V.y) - (U.y * V.x);
//Debug.Log("Normal: x:" +normal.x+ " y:" +normal.y+ " z:" +normal.z+ "\n");
triangleList.Add(triangleP1);
if (normal.z < 0)
{
triangleList.Add(triangleP2);
triangleList.Add(triangleP3);
}
else
{
triangleList.Add(triangleP3);
triangleList.Add(triangleP2);
}
}
}
It really does look like the UVs are not mapped correctly. Have you tried just generating the mesh, then applying a simple texture to a material with a default diffuse shader, and seeing if the mesh does have the UVs mapped correctly?
I still think its the UVs. Looking at the last line of the VERT_UV info :
1272 0728 1272 0728
UVs are usually between 0 and 1. When line 145 is changed to :
uvList.Add( new Vector2( x * 0.001, y * 0.001 ) );
then it starts to look normal, but is still tiled on the X by 1.272
I wrote a uJS script to test your $$anonymous$$ultiprojector$$anonymous$$esh0.txt (it was the only way I could understand what is going on!). The mesh constructs as your screenshot, but the UV mapping is off. You can see the texture I used is just a 4x4 primary colour image.

Answer by whydoidoit · Apr 25, 2013 at 10:42 PM
Your UV coordinates in the imported file are really big numbers :) UVs in unity are a value between 0 and 1 reflecting the width/height of the texture at 1,1 and the other corner at 0,0.
I'm not sure what the scale of those UVs is, but they need dividing down to get the correct scale for Unity.
Ow okay thanks, I shall try to scale them they are on they were scaled on the output resolution from 0 to 1280 and 0 to 720
Hahaa, while I was posting that wall of text, the answer was given.
XD
1280f and 720f, wouldn't want c# to get confused :)
I think. I forget when it's necessary so i just f all my floats now. :S
Thank you everyone, I managed to fix the problem, the problem was indeed my UV coordinates. Which needed to be scaled to a float value between 0 and 1. Again thank you guys a lot. The amazing fast replies, I love the Unity Community.
Your answer