Get a color on raycast whatever the source of the color

Hello,

I am making a simulator, in which the user can place a color sensor. Then I have the script of the color sensor which have to find the color in front of it. So here is the part of the script:

Color color = Color.black;
rayCursor = new Ray(transform.position, transform.forward);
if (Physics.Raycast(rayCursor, out hitInfos, 0.02f))
 {
     Renderer rend = hitInfos.transform.GetComponent<MeshRenderer>();
     if (rend != null)
          Texture2D tex = (Texture2D)rend.material.mainTexture;
          color = rend.material.color * ((tex == null) ? Color.white : tex.GetPixel((int)hitInfos.textureCoord.x, (int)hitInfos.textureCoord.y));
      }
  } 

However, this script seems to work only when the sensor faces a simple gameobject like a yellow sphere or a red cube…
The problem is that the collider doesn’t always fit the object’s mesh, but the sensor have to work in all situation (fitting to the reality since it is a simulator), the gameobject can as well be a Terrain.

How can I do that ?

Thanks in advance. (Sorry for my bad English)

1 Answer

1

If you want the colour as displayed on screen accounting for lighting, effects etc., what you’ll need to do is…:

  • Set your camera to output to a rendertexture
  • Copy the rendertexture to a regular texture using ReadPixels
  • Convert the coordinates of the “colour sensor” to screenspace relative to the camera (using WorldToScreenPoint)
  • Then use GetPixel to retrieve the pixel value at the corresponding screen coordinate.

Also, what do you do when you know the colour value? The slow bit here is the interface retrieving the value from the GPU to the CPU ( ie. reading the pixels from a render texture to a regular texture). But do you need to do that? Could you do all the remaining processing on the GPU side?

@Eric5h5: I did what you said. Now I have: Texture2D image = new Texture2D(1, 1); image.ReadPixels(new Rect(cam.targetTexture.width/2, cam.targetTexture.height/2, 1, 1), 0, 0); image.Apply(); color = image.GetPixel(0, 0); But the fps still drops almost as much... I also tried to reduce the camera rect ( cam.pixelRect = new Rect(0, 0, 1, 1); ) but the fps is barely higher, and the script no more works (I always get black {0,0,0}).

@tanoshimi: "what do you do when you know the colour value?" Everything I do is displaying it... "But do you need to do that?" I don't know. As I said, this script comme from [the RenderTexture.active example][1], and I am on uncharted ground... By the way, here are the performance stats: - When there is no sensor: main: 14ms ; render thread: 1ms - When there is a sensor: main: 21ms ; render thread: 16ms [1]: https://docs.unity3d.com/ScriptReference/RenderTexture-active.html