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

Texture projection to generated mesh once

Discussion in 'Shaders' started by Sheeks, Dec 7, 2021.

  1. Sheeks

    Sheeks

    Joined:
    Jun 9, 2017
    Posts:
    11
    Hi,
    i want to map a camera feed Texture from an AR device to a generated planar Mesh with correct UVs in 3D space. Is it possible to map a texture to a generated mesh (2D planar) with tex2dproj without the texture changing with camera movement? Meaning to substract / inverse the camera movement to stick the texture position to the mesh? So the UV position is initialized kind of once?

    Here is the basic shader im using:
    Code (CSharp):
    1. v2f vert(appdata v)
    2.             {
    3.                 v2f o;
    4.                 o.pos = UnityObjectToClipPos(v.vertex);
    5.                 o.uv  = ComputeScreenPos(o.pos);
    6.                 return o;
    7.             }
    8.  
    9.             fixed4 frag(v2f i) : SV_TARGET
    10.             {
    11.                 float4 col = tex2Dproj(_MainTex,i.uv);
    12.                 float4 result = col;
    13.                 return result;
    14.             }
    Or is there a way to adjust the generated UVs on the mesh without using the shader?


    So there is a Background with a UV pattern. In front of that is the generated Mesh (white plane). How can i achieve to get the correct mapping of the pattern if i insert the same Texture to the Mesh (independet from the camera positon/angle)

    I hope it is somehow understandable what i wanna try to do.
    Thanks for any kind of help! :)
     
    Last edited: Dec 7, 2021
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    You can grab the camera's projection and view matrices at the moment in time you want to use, and pass that to the shader. Then use that matrix instead of the actual camera matrix to calculate the appropriate projected UVs. You could also grab that object's current matrix so it can even move after the fact and not affect the projection.

    Code (csharp):
    1. // c#
    2.  
    3. // calculate the current model view projection matrix
    4. Matrix4x4 MVP = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false) * cam.worldToCameraMatrix * transform.GetComponent<Renderer>().localToWorldMatrix;
    5.  
    6. // pass the matrix to the shader by setting it on the material
    7. material.SetMatrix("_MyProjectionMatrix", MVP);
    8.  
    9. // shader code
    10. // outside a function, inside the CGPROGRAM block
    11. float4x4 _MyProjectionMatrix
    12.  
    13. // in the vertex function
    14. float4 projClipPos = mul(_MyProjectionMatrix, float4(v.vertex.xyz, 1.0));
    15. i.uv = ComputeScreenPos(projClipPos);
     
  3. Sheeks

    Sheeks

    Joined:
    Jun 9, 2017
    Posts:
    11
    You are awesome! Thank you so much for the hint! Works like a charm!