Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to fit a texture to a mesh?

Discussion in 'General Graphics' started by sildeflask, Sep 4, 2023.

  1. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    I am capturing a screenshot from my camera

    I now want to display this screenshot on a mesh

    But I want it to fit it so the mesh displays only the area of the screen it was overlapping with on the camera view

    So far I have the screenshot, I sample the texture in a shader, and I assign the material to the mesh renderer

    However the screenshot is crammed to fit inside the shape of the mesh ( I dont know where to go from here )

    Here is an image of where I am:
    Untitled2.png
    I assume I have to make some calculation to figure out the aspect ratio of the mesh and how much space the mesh is taking onscreen?(position, scale and distance to camera??)

    And then somehow I have to send these calculations to the shader to correctly tile the texture on the mesh?

    But I dont know how I can do this

    Any help would be appreciated, thanks
     
    Last edited: Sep 4, 2023
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    From what you've described above, you seem to be simply saying that you're using the whole texture surface in the mesh so this is why; nothing to do with aspect ratio.

    Are you not using the correct texture coordinates (UV) in the mesh? You calculate that regions' UV coordinates and use them.

    https://docs.unity3d.com/ScriptReference/Mesh.SetUVs.html
     
    wideeyenow_unity likes this.
  3. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Particularly I only know how to edit this in Blender, but in Unity a simple(not precise) way, would be to modify the materials offsets. As you can set cut level, and offset to a particular section of the original image. But this doesn't work well if needing many parts of said image as you'd have to make a material for each different object to render it.

    I think there is a way to set UVs with code, in Unity, but sounds complicated
     
  4. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    So I have a tiling and offset node that can kind of rescale the texture by plugging it in the UV of the sample texture 2D

    But how do I calculate the UV coordinates of a region? How do I get a region from the position and scale of a mesh relative to a camera?

    Right now what I have is a screenshot - 1920x1080 (16:9)
    When I place this in a material its crammed in as I said above

    I dont think I need to make many materials since I can use material property blocks? If I need multiple meshes

    PS: I do think I will need scripting for this no?
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    If you're asking about ShaderGraph (?) then you should really mention that so we know; also best to post it on the ShaderGraph forum.

    I can move this thread there if you wish?
     
  6. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    pls no why move the thread around

    I just need math, how can I find the rect of the screen a mesh is occupying
    OR
    how can i find the UV needed

    I dont need shader graph at all, it was just an idea
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    I don't have the details of your implementation so I have no idea what part of Unity you're specifically asking about. You're just asking broad questions and expecting an answer. You hinted at ShaderGraph hence being asked about it. Your original post was in scripting but you're asking graphics questions (Mesh). I provided the API on how to set the UV. Now you want "math" but I have no details about where you are with it.

    Provide some specific details for us to plug in the specific details you require.
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
  9. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    I guess I was unclear on my original post?

    I have a mesh, that mesh is a plane inside the view of the camera

    I want to take a screenshot of my camera view

    And I want to render that screenshot on the mesh

    BUT ONLY THE EXACT PART THAT WOULD LINE UP WITH THE MESH
    (at the moment when i put it in a material it just crams in the whole screen)

    Basically - Crop the screen based on the mesh, and display the cropped area on the mesh.

    heres my diagram again

    Untitled2.png
    You told me set UVs, but I have no clue what you mean.

    Can you explain in more detail how setting UVs would solve my issue?

    If any point is unclear please let me know, I will try again to explain sorry
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Provide some implementation details not a description.

    First, do you know what UVs are? If not then it's better to say! :) I provided a link that gave you an exact API. You can use this to specify what part of the texture the vertices of a mesh use. This is what UVs are so I'm not sure why I'd need to provide more detail if you know what UVs are.

    Given a Mesh which has a material that is presenting the texture, you can set the vertex UVs to specify what part of the texture each is assigned to. In this way you're selecting what part of the texture is being used i.e. a "window" on the texture. This is just UV stuff.

    Follow the link I gave you previously, it explains that there! https://docs.unity3d.com/ScriptReference/Mesh.SetUVs.html

    See section on UVs (lots of these online).
    https://catlikecoding.com/unity/tutorials/procedural-meshes/creating-a-mesh/
     
  11. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    You have given me the API to set UVs, but you didnt say what parameters I should input to get my desired result

    Code (CSharp):
    1. Mesh.SetUVs(???,???);
    what to put in ??? to get the window that corresponds to the mesh
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    You're asking me how to use it? That's in the scripting reference.

    If you're asking me what values to put in then how could I possibly know that? As I've said above, I don't have any details of your project (just a vague description) so I cannot give you values or variables or calculations to use.
     
  13. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    well that was the whole point of the post, there must be some math that works for any size mesh and gets the corresponding UVs. If you dont know what to put in the UVs they i know even less.

    Should I make a new thread, this time dedicated on finding the UV values?
     
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Do you know what UVs are? I asked above. UVs relate to the texture size, not the mesh "size". As the docs state, they're normalized texture coordinates.

    In fear of this becoming a tutorial: Given a texture, 0.5, 0.5 is the center of the texture. With your texture, you have a coordinate of what you want, you need to turn that into texture coordinates.

    No, you don't need another thread but in the end, it's up to you.
     
  15. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    you are not obliged to give me a tutorial but Im thankful for it nonentheless

    Im sure that given a position of a rectangular area inside of the view of the camera there must be some way of get its rect in screen space, I feel like it involves a lot of math and code to find it
     
  16. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    839
    So are you trying to make this work specifically for a rectangular mesh that is always facing the screen? Or is this something that needs to be more general and work for any mesh that could exist in 3D space? Also, is the screenshot taken of the full screen or just some part of it? Depending on your answer this can range from pretty simple to pretty complex
     
  17. sildeflask

    sildeflask

    Joined:
    Aug 16, 2023
    Posts:
    142
    -Mesh always facing the screen

    - The only part I really need of the screen is the part that is going to be displaying in the mesh
    (anyway its always going to be the region occupied by the mesh in the camera view.)

    The mesh is always a rectangle, but it might change position and sometimes have different scale to be a square/ or wider than it is tall, or be on a different position on the screen

    thanks
     
  18. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    839
    In that case you have it really really easy. Just get the screen position of each vert in the quad and convert it to a percentage of the screen's size. That is your UV coord for that vertex.

    Off the top of my head some pseudo code would be something like:
    Code (CSharp):
    1.  
    2. Camera camera;
    3. var trans = QuadObject.transform;
    4. var filter = QuadObject.GetComponent<MeshFilter>();
    5. var mesh = filter.mesh //or use sharedMesh if that is more appropriate in this case
    6. var verts = mesh.verticies;
    7. var uvs = new Vector2[verts.length];
    8.  
    9. for(int i = 0; i < verts.Length; i++)
    10. {
    11.     //transform the vert to world space, then screen space in pixels, then finally a percentage of the screen's space in pixels.
    12.     var worldVert = transform.TransformPoint(verts[i]);
    13.     var screenVert = camera.WorldToScreenPoint(worldVert);
    14.     uvs[i] = new Vector2(
    15.         screenVert.x / camera.pixelWidth,
    16.         screenVert.y / camera.pixelHeight
    17.         );
    18. }
    19.  
    20. //assign calculated uvs back to the mesh
    21. mesh.uv = uvs;
    This code might not be 110% right. It's been a while since I had to do any mesh manipulation so I might have gotten some details wrong or the direction of the UVs might be flipped but it should get your started. heck, it might even work on the first try!
     
    sildeflask likes this.