Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
avatar image
0
Question by PvTGreg · Apr 22, 2021 at 07:56 PM · raycastcolormeshrenderer

Getting color from mesh renderer causing crash

Hi,

so i am trying to get the color of a specific part of my randomly generated "terrain" mesh so that i can determine if it is grass or sand ect. i generated my mesh at runtime and it has textures applied at differant heights. one material with a few differant textures.

I am trying to eventually place prefabs randomly on the grass only. my current aproach is to create a grid in the sky above the ground then from each grid point i raycast down and check to see what color it hits and compare it with the grass texture.

after hours of reading i came up with this but it just crashes unity. for reference my grid is 100x100 i have stripped it back and it seems to crash at the last stage where i check to see if the mesh vertices == triangle and i get no debug log

 public void CheckColor()
     {
         mesh = GameObject.Find("/Map Generator/Terrain Chunk").GetComponent<MeshFilter>().mesh;
         for (int i = 0; i < grid.GetLength(0); i++)
         {
             for (int o = 0; o < grid.GetLength(1); o++)
             {
                 RaycastHit hit;
                 if (Physics.Raycast(grid[i, o].GetComponent<Transform>().position, Vector3.up * -1, out hit))
                 {
                     int v0Index = hit.triangleIndex * 3 + 0;
                     int v1Index = hit.triangleIndex * 3 + 1;
                     int v2Index = hit.triangleIndex * 3 + 2;
                     Vector3 triangle = new Vector3(v0Index, v1Index, v2Index); 
                     Color colour;
                     for (int p = 0; p < mesh.vertices.Length; p += 3)
                     {
                         if (mesh.vertices[p] == triangle)
                         {
                             colour = mesh.colors[p];
                             Debug.Log(colour);
                         }
                     }
                         
                         /*Renderer rend = hit.transform.GetComponent<MeshRenderer>();
                         Texture2D tex = rend.material.mainTexture as Texture2D;
                         if(tex == Grass)
                         {
                             GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                             cube.transform.position = hit.point;
                         }*/
                 }
             }
         }
     }
Comment
Add comment · Show 1
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
avatar image PvTGreg · Apr 22, 2021 at 08:04 PM 0
Share

specificly looping through mesh.vertices.length is causing issue. is there a better aproach to this?

2 Replies

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

Answer by Bunny83 · Apr 23, 2021 at 09:49 AM

Well, first of all, are you really experiencing a crash or just a hang?

There's a lot confusing information about your issue. First of all if the object has a material and you are using a texture on the triangles, what exact role does the vertex color has in your case? If you use a shader that uses textures, the vertex color is usually ignored / not present. Maybe you wanted to get the color from the texture? In that case the color array is completely useless.


Though, apart from those uncertainties, your code just makes no sense ^^. The triangle indices you generate from the "triangleIndex" are indices and not 3d coordinates. Those are the indices into the vertex arrays that make up the 3 corners of the triangle that the ray has hit.


The reason why you most likely get a hang is because you have many nested for loops which probably take ages to complete. Further more: never ever use mesh.vertices or mesh.triangles in a loop. Those properties will create a new managed array each time you use it. If you want to work with the vertices of a mesh, you have to store that array in a local variable and use that variable instead. Otherwise you will create a huge number of arrays. Specifically your inner most loop iterates through all vertices in mesh and for each iteration you create / recreate the vertices array twice. Since that loop runs for every of your grid cells you can multiply that number by the columns and rows of your grid. You are most likely allocating gigabytes of memory with that loop ^^.


So, if the point of that script was to read / extract the color on the surface of the mesh at each grid position and the triangles in the mesh are actually textured, there are a few requirements for this to work. First of all the used texture need to be readable. For this you have to enable read / write in the texture importer. Otherwise you can not access any of the color information of the texture. Second, in order to read the right color from the texture you have to use hit.textureCoord. With that texture coordinate you can now use GetPixelBilinear on the used texture. Note if the mesh uses more than one material (so if it has submeshes) it's getting more complicated since you have to find the right submesh in order to know which material is the right one. Though if the mesh only has a single submesh and a single material, it's kinda trivial.


Keep in mind that hit.triangleIndex as well as hit.textureCoord only work when hitting a mesh collider. Primitive colliders do not provide any mesh related information. Also the MeshCollider you hit has to belong to the mesh you're looking for. So it's generally better to get the mesh from the meshcollider you have hit.

 Material mat = null;
 for (int i = 0; i < grid.GetLength(0); i++)
 {
     for (int o = 0; o < grid.GetLength(1); o++)
     {
         RaycastHit hit;
         if (Physics.Raycast(grid[i, o].transform.position, -Vector3.up, out hit))
         {
             if (mat == null)
             {
                 var rend = hit.collider.GetComponent<MeshRenderer>();
                 if (rend != null)
                     mat = rend.sharedMaterial;
             }
             Texture2D tex = mat.mainTexture as Texture2D;
             if (tex != null)
             {
                 Color col = tex.GetPixelBilinear(hit.textureCoord.x, hit.textureCoord.y);
                 // here you have the color of the point on the surface of the mesh.
             }
         }
     }
 }

Note that this does only query the used texture at the uv coordinate of the mesh. If you use some fancy shader that dynamically assigns a different color / texture depending on the height, you can not read that out from the static geometry. You either have to implement the same logic you do in the shader here, or you actually have to render the topview into a rendertexture and extract the color from there. None of those approaches are that pretty.


It would be much easier to help if we know more about what this is actually about. What do you do with the color from each of those positions? Why and for what do you need them?

Comment
Add comment · Show 1 · 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
avatar image PvTGreg · Apr 23, 2021 at 11:52 AM 0
Share

Thankyou for the reply that has helped me understand what i written a bit more. the end goal is to just see if there is a grass texture on the mesh as apposed to sand or rock ect that way i can place prefabs accordingly the mesh has one materiel with a custom shader that places the texture on it depepending height.

my code was the end result of reading anything i could about sampling color from a specific triagnle but to be i didnt really understand much of it.

after typing this comment out it would probably be easier to just use the same logic i am using to place textures on the heights to place prefabs at certain heights but it would be good to know how to do the texture checkign aswell

Edit: But yes i do use a fancy shader so the above code does return nothing.

avatar image
0

Answer by Llama_w_2Ls · Apr 23, 2021 at 02:59 AM

Mesh.colors returns an empty array if you havent assigned any colors prior to creating the terrain. See the doc here

Comment
Add comment · Show 1 · 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
avatar image PvTGreg · Apr 23, 2021 at 07:57 AM 0
Share

in this case i am not using unity's terrain but a plane mesh generated at runtime and a heightmap applied then textures applied to the material at diferant heights

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

165 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

Related Questions

Create torus with different colored segments 1 Answer

How to fill the inside volume of a 3D mesh with color? 0 Answers

How to find out if raycast dont hit anything 1 Answer

Help - Selection System 1 Answer

Change Color of Object when NOT looking at it 1 Answer


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