How to get the colors of the vertices in a mesh? [or average color of a triangle]

Hi all,

I’m trying to obtain the color of the vertices in a mesh once a directional light makes its action on the mesh. However all the values for all the vertices that I’m obtaining are exactly the same: RGBA(255, 255, 255, 255), and this is not correct since my mesh is grey and it has parts of shadows.

The code is:

Mesh _mesh_runtime = _67P_3Dobject.GetComponent<MeshFilter>().mesh;
Color32[] vertex_colors = _mesh_runtime.colors32;
    
Debug.Log(vertex_colors[index_of_vertex].ToString());

My mesh has a default diffuse shader. Do you know what is happening?
Cheers and thank you!

The vertex colors do not change based on light. The are used by a shader as one input in determining the color of the pixels it renders.

Thanks robertbu. My aim is to obtain the color of each of the triangles in the following image, so I thought that a good way was to obtain the color of the vertices in each triangle and make the average. If not, How could I do this? Should I use another approach? [33744-2.png|33744]

I don't have an in-depth knowledge of the area of Unity that you need to solve this problem. I'd be examining lightmapping. If you can get access to the baked textures, you can use the uv coordinates associates with the vertices to get the color. But that is only a untested idea on my part.

Hi JohnyHilly, thank you very much for your great answer! It can be very useful, anyway, what should I do if I need to compute the brightness of the triangle, rather than just facing? I mean, you've talked about brightness dropoff, but, how Can I do this? Thank you very much!

2 Answers

2

if you have unity pro… render your camera to a render texture, then you can sample any of the pixel’s rgb color that you want from the render texture.
You’ll just need to convert your screen space co-ordinate, into a texture space co-ordinate.

alternatively… use vectors. compute facing angle or brightness yourself.
vec1 = polygon . normal

vec2 = light.position - poly.position //for a spot or point light

or

vec2 = -light.direction //for a directional

float dp = Vector3.dot(vec1, vec2);

if(dp>0) //threshold check

visible = true;

else

visible = false;

//1=facing (bright) 0 = 90 degrees(dark) -1 = facing opposite direction (dark)

//if you need to go further and use brightness rather than just facing… you can dp to approximate lighting brightness, if you want a threshold.

You don't need rendertextures, just read the screen pixels, however either way that only works if the vertex in question is actually visible on-camera so it's not really a feasible solution in most cases.

you point the render texture camera along the same vector as whatever you need... the raycast, or the regular screen camera. screen pixels don't always work (might be off camera or behind)

another thing you could do is do a raycast to the triange... get the surface normal. Then do your own dot product lighting calculation, vs the light source direction, to compute brightness on your own. Depending on how accurate you want it... This can be a simple front face/backface check against the light vector (from light to the polygon) or apply a dot product to a cos() brightness dropoff to determine surface brightness. (see answer above)

Hi JohnyHilly, thank you very much for your great answer! It can be very useful, anyway, what should I do if I need to compute the brightness of the triangle, rather than just facing? I mean, you've talked about brightness dropoff, but, how Can I do this? Thank you very much!

How could I compute the brightness/color of a particular triangle due to the influence of a directional light? I need like a kind of occlusion value which indicates how illuminated or occluded is a triangle. Is this possible? I've done the cross product recommended by JohnyHilly but it doesn't work for triangles which are occluded by other triangles...I mean, it only works for convex shapes...

Easy, I’ve solved the problem placing the main camera on the normal vector of each facet of the mesh, and making the camera point to that facet and rendering the color of that facet (using a very low value of the field of view of the camera to constraint the camera pointing). Consequently, I can obtain a rendered image of each facet in the mesh, thus allowing me to compute the final brightness of each one ;).