Find world position of a Texture2D

My case is .. a texture's colour alpha is compared to an objects A texture colour alpha when this object is hit. I want to position of where this happened (from pixels)

What I have is a RaycastHit.textCoord of object A which I think may be used to find the position. But the texture coordination is then changed a bit, this is why I cannot use the hitpoint mentioned earlier.

What I need is somewhat a way to change pixels back to RaycastHit.textCoord which in turn it is changed to a position. But I guess this way is not possible, I don't know.

Below is a piece of code relevant

function CheckAlpha (texture:Texture2D, pixelUV:Vector2, directionCheck:boolean, other:Collider):boolean {
//pixelUV is the RaycastHit.textCoord
var uvX:int = pixelUV.x * texture.width;
var uvY:int = pixelUV.y * texture.height;
if (directionCheck) {
//This loop will pick up the pixel (a new uvY) from the
texture which is not transparent, starting from the bottom
till the uvY. If a pixel is picked up, another texture is
placed around the uvX and the new uvY. How can I get world
coordinates of this other texture?
for(var i = texture.height; i >= uvY; i--){
if(texture.GetPixel(uvX, i).a != 0.0)
return ApplyTexture(texture, uvX, i, shipDamageTexture, shipHoleTextureArray);
}
}

the texture2D is neither a GUItexture nor a Plane. It is created when on a hitpoint between two objects.

To be more specific .. a the a texture's colour alpha is compared to an objects A texter colour alpha when this object is hit. I want to position of where this happened (from pixels)

What I have is a RaycastHit.textCoord of object A which I think may be used to find the position. But the texture coordination is then changed a bit, this is why I cannot use the hitpoint mentioned earlier.

What I need is somewhat a way to change pixels back to RaycastHit.textCoord which in turn it is changed to a position. But I guess this way is not possible, I don't know.

1 Reply

Ok, so you want to find the 3D position of a given texture element in the mesh. You're lucky: I answered recently a question about triangle interpolation, and found all the geometry needed in your case.
The basic idea is: given the UV coordinates of some texture point, iterate through the triangles until you find the one that contains it, then interpolate the triangle vertices to find the 3D point in the mesh; since mesh coordinates are in local space, you must also convert it to world space with transform.TransformPoint.
In order to check whether the point lies inside a given triangle, you can calculate the *barycentric coordinates* of the UV point: if any of them is negative, the point is outside the triangle. If the point is inside the triangle, the interpolation is incredibly easy to do because all it needs is the barycentric coordinates we've just calculated: just sum the triangle vertices multiplied by the respective barycentric coordinates, then apply TransformPoint to convert the resulting position to world space.
The function UvTo3D below does this: it must be attached to the mesh, and you must pass to it the UV coordinates of the desired point. The function gets the triangles, vertices and uvs of the mesh and looks for the point in the UV map. If the point lies inside one or more triangles, the 3D position in the first triangle found is returned; if not, the function returns Vector3.zero:

If you're looking for a kind of "color picker" that gets the original texture color of the point under the cursor, this can be done - but with several restrictions:
1- The clicked object must have a mesh collider to return a valid UV pair in the RaycastHit structure;
2- The texture must have Read/Write enabled in the Import Settings (click the texture in the Project view to show its Import Settings, then select Texture Type = Advanced and mark Read/Write enabled);
3- A single pixel in the screen may correspond to lots of texture elements, thus the UV pair returned by RaycastHit may not be precise enough to detect small areas in the object.
The script below gets the texture color of the object point under the mouse, and you can compare it to whatever you want. It's based on the RaycastHit.textureCoord example, and only works for mesh colliders and textures marked as read/write. Attach it to the camera:

Ok, so you want to do the opposite: given a texture element, find its world position in the surface of the object "painted" with this texture.
Supposing that your model doesn't use the same texture portion to cover more than one part of the model (what would make the job impossible), finding a given texture position in the model is a pain in the ass: you should convert the texture position to a UV pair (just divide by width and height), then iterate through the mesh triangles, getting each triangle in UV coordinates until the one that contained the UV point was found, and finally interpolate this triangle vertices to find the point in model space (you should use transform.TransformPoint to convert it to world space, if needed). If you want to find a single point, this may be tolerable - but forget about doing this for each element in the texture!
Please explain for which purpose you're trying to do such weird thing - probably there's another much easier way to reach the same result without doing all this work!

That's a pretty neat idea. In my case I have a map I'm pulling in from Google Maps and using it as a texture on a plane. I'd like to place 3D objects on top of the location markers--I can get pixel coordinates of the markers in the texture. So I think this method will work. Once I work out the math.

I edited my answer and included a function that does what you want. Things became much easier than I supposed because the main search is done in 2D space, and also due to the fact that the "point inside triangle" test generates all we need to interpolate the point.