Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Zoobidoobie · Apr 27, 2020 at 10:56 PM · texture2dmeshrendereruv mapping

Can someone help with applying a generated texture onto a generated mesh?

Help! I am trying to create a procedurally generated terrain, and a procedurally generated texture and apply the texture to the terrain. I already have the terrain generation down, along with the texture generation. The issue I am having is whenever I apply the texture to the terrain, only the first pixel of the texture is showing up, but it is showing up on the entire terrain. I figured it has something to do with the UV map i've created for the terrain's mesh. I've verified that it is only the first pixel of the texture, by writing the first pixel of the texture to magenta, and the whole terrain turns magenta. So I'm guessing that there is something wrong with the UVs and that the UV map is making a bunch of the same first pixel over and over again. I don't know though.

I didn't include the code dealing with the triangles for the created mesh, because the mesh works just fine. I'm able to have proper collisions and shading with the generated terrain. It just won't have the WHOLE texture applied to it. The terrain image is generated based on the generateHeight() function, and also works just fine. I can view the generated picture in the inspector and it matches exactly what the terrain height looks like.

Any assistance would be greatly appreciated! I've been searching through google for days now. This is the first time I've asked a question here, so my apologies if I haven't included everything you need, please let me know!

My terrain is x units long by z units deep. The texture is x by z pixels, so that one pixel should correspond to each vertex of the terrain. I understand that the UV map should go from 0-1 over the entire terrain, so that would be 0-1 divided by the number of vertices in the x and z, or in other words U/xUnits by V/zUnits. Some snippets of code:

 Vector2[] uvsArray; //Array to hold the UV coordinates
 Vector3[] verticesArray; //Array to hold the terrain vertices
 public int verticesX = 10; //Total width of the terrain
 public int verticesZ = 10; //Total depth of the terrain
 void CreateUVsArray()
 { 
   verticesArray = new Vector3[(verticesX +1) * (verticesZ+1)];
   uvsArray = new Vector2[(verticesX +1) * (verticesZ+1)];
   //Start with setting the uvsArray size to the same size as the vertices array for the terrain
   for (int i = 0, z = 0; z < verticesZ; z++)
   {
      for(int x = 0; x < verticesX; x++)  
      {  
         // Loop through and generate the verticesArray values, works just fine  
         verticesArray[i] = new Vector3(x, generateHeight(), z);  
         // Create a UV Array with the points of the terrain mesh divided by the total vertices for each x and z  
         uvsArray[i] = new Vector2(x / verticesX, z / verticesZ);  
         i++;  
      }  
   }  
 }

I update the created mesh in the following

 void UpdateMesh()
 {
   terrainMesh.Clear();
   terrainMesh.vertices = verticesArray;
   terrainMesh.triangles = trianglesArray;
   terrainMesh.uv = uvsArray;
   terrainMesh.RecalculateNormals();
   terrainTexture.Apply();
   terrainTexture.wrapMode = TextureWrapMode.Clamp;
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Zoobidoobie · Apr 28, 2020 at 03:22 PM

Solved! Here's the code.
I figured it out, was missing some key components. What it boiled down to was that I forgot to set the meshRenderer materials maintexture. I thought that since I could see it in the inspector, that it was already set. But since this is all being created at runtime, I guess that wasn't the case. I'm honestly still not sure on the technicalities of why I could see it in the inspector if it wasn't set, but hey it works now. Hope it helps for anyone wanting to create a procedural mesh, a procedural texture, and apply the two together.

 void Awake()
     {
         meshRenderer = GetComponent<Renderer>();
         terrainMesh = new Mesh();
         GetComponent<MeshFilter>().mesh = terrainMesh;
         CreateMesh();
         UpdateMesh();
         MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>();
         meshCollider.sharedMesh = terrainMesh;
 
     }
 
     //******************************************************
     //Generate The Terrain Mesh
     //******************************************************
     void CreateMesh()
     {
         //******************************************************
         //Create Vertices Array
         //******************************************************
         CreateVerticesArray();
         //******************************************************
         //Create Triangles Array
         //******************************************************
         CreateTrianglesArray();
         //******************************************************
         //Create UVs Array
         //******************************************************
         CreateUVsArray();
         //******************************************************
         //Create Colors Array
         //******************************************************
         CreateColorsArray();
     }
 
     //******************************************************
     //Create UVs Array
     //******************************************************
     void CreateUVsArray()
     {
         //UVs count must always be the same amount as the vertices!
         uvsArray = new Vector2[(verticesX + 1) * (verticesZ + 1)]; 
         
         for(int i =0, z = 0; z <= verticesZ; z++)
         {
             for (int x = 0; x <= verticesX; x++)
             {
                 //Scale the UV positions by the current vertices position / (the total vertices * the map scale)
                 uvsArray[i] = new Vector2(verticesArray[i].x/ (verticesX * mapScale), verticesArray[i].z / (verticesZ * mapScale));
                 i++;
             }
         }
     }
 
     //******************************************************
     //Create Colors Array
     //******************************************************
     void CreateColorsArray()
     {
         //My texture is a one to one for the vertices array, so the color array should be too
         colorsArray = new Color[(verticesX + 1) * (verticesZ + 1)]; 
         terrainTexture = new Texture2D((verticesX + 1) , (verticesZ + 1));
         
         for (int i = 0, z = 0; z <= verticesZ; z++)
         {
             for (int x = 0; x <= verticesX; x++)
             {
                 float heightOfVertex = Mathf.InverseLerp(minimumTerrainHeight, maximumTerrainHeight, verticesArray[i].y);
                 // Specify gradient here if you want a gradient applied to your terrain
                 colorsArray[i] = terrainGradient.Evaluate(heightOfVertex);
                 //Using setPixel for each pixel worked, whereas using setPixels later with the whole array didn't.
                 terrainTexture.SetPixel(x, z, colorsArray[i]);
                 i++;
             }
         }    
     }
 
     //******************************************************
     //Create Vertices Array
     //******************************************************
     void CreateVerticesArray()
     {
         verticesArray = new Vector3[(verticesX + 1) * (verticesZ + 1)];
 
         for (int i = 0, z = 0; z <= verticesZ; z++)
         {
             for (int x = 0; x <= verticesX; x++)
             {
                 float y = GenerateTerrainHeight(x, z);// change this function to be a terrain generation function
 
                 verticesArray[i] = new Vector3(x * mapScale, y, z * mapScale);    // Scale Goes in here
                 i++;
             }
         }
         
     }
     
     //******************************************************
     //Create Triangles Array
     //******************************************************
     void CreateTrianglesArray()
     {
         trianglesArray = new int[verticesX * verticesZ * 6];
         int vert = 0;
         int tris = 0;
         for (int z = 0; z < verticesZ; z++)
         {
             for (int x = 0; x < verticesX; x++)
             {
 
 
                 trianglesArray[tris + 0] = (vert + 0);
                 trianglesArray[tris + 1] = (vert + verticesX + 1);
                 trianglesArray[tris + 2] = (vert + 1);
                 trianglesArray[tris + 3] = (vert + 1);
                 trianglesArray[tris + 4] = (vert + verticesX + 1);
                 trianglesArray[tris + 5] = (vert + verticesX + 2);
                 vert++;
                 tris += 6;
             }
             vert++;
         }
     }
 
     //******************************************************
     //Update The Mesh
     //******************************************************
     void UpdateMesh()
     {
         //Cleared the mesh to discard any unwanted legacies, not sure if needed though
         terrainMesh.Clear();
         //Set the mesh vertices
         terrainMesh.vertices = verticesArray;
         //Set the mesh triangles
         terrainMesh.triangles = trianglesArray;
         //Set the mesh UVs
         terrainMesh.uv = uvsArray;
         //Recalculate all the normals for the mesh
         terrainMesh.RecalculateNormals();
         //This was key, making the meshRenderer material set to the generated texture
         this.meshRenderer.material.mainTexture = terrainTexture;
         //Don't forget to apply the texture, this is a second step that was key.
         terrainTexture.Apply();
         //Set your wrap mode to the desired mode. I needed it clamped.
         terrainTexture.wrapMode = TextureWrapMode.Clamp;
     }




Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

203 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to get the specified material for a given uv coordinate 0 Answers

Distorted/Warped Textures On Character Model After Bundling For Tabletop Simulator/In A Build 1 Answer

reuse texture between quad 0 Answers

Trying to create a freaking math clone. new learner and very low coding skills. Having trouble with setting the time limit for the process.Need Help? 1 Answer

SetPixels edge pixels 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges