Search Unity

Camera rotation in shader (solved)

Discussion in 'Shaders' started by Emiliana_vt, Dec 1, 2018.

  1. Emiliana_vt

    Emiliana_vt

    Joined:
    Apr 7, 2018
    Posts:
    13
    I'm using the shader like the one at the end of this post to detect objects using a camera and a 1x1 RenderTexture. It gives me the UV coordinates and a surface ID and works fine so far.

    Now I would like to figure out the camera orientation with respect to the UV coordinates it is pointed at. I found some ways to get the camera view direction, but I can't figure out if what I'm trying to do is possible at all. For example, here:



    Here we can see a camera pointed straight at a quad, with both of them being rotated around the Z axis. I am looking for the angle between those two rotations. In the real case, the camera can also be looking at whatever surface at an angle, but I am mainly interested in the camera's roll angle with respect to the UV coordinates of the surface it is looking at. Is it possible to find this angle? I would be really happy about any pointers in the right direction.

    Converting the shader to a vertex and fragment shader wouldn't be a problem if it's necessary to do this.

    Code (csharp):
    1. Shader "Detect" {
    2.     Properties {
    3.         _MainTex ("Base (RGBA)", 2D) = "white" {}
    4.         _SurfaceID ("Surface ID", Float) = 0.0
    5.     }
    6.     SubShader {
    7.         Tags { "RenderType"="Transparent" "Queue"="Transparent" }
    8.         LOD 0
    9.              
    10.         CGPROGRAM
    11.         #pragma surface surf Lambert alpha
    12.         sampler2D _MainTex;
    13.         float _SurfaceID;
    14.        
    15.         struct Input {
    16.             float2 uv_MainTex;
    17.         };
    18.         void surf (Input IN, inout SurfaceOutput o) {
    19.             o.Emission = float3(IN.uv_MainTex.rg, _SurfaceID);
    20.             o.Alpha = 1.0;
    21.         }
    22.         ENDCG
    23.     }
    24. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    A mesh's tangent vector is the UV orientation. The tangent points in the direction of the UV's x flow. The UNITY_MATRIX_V has the world to view space matrix, which holds the camera's orientation. You could extract the right vector from that, but it will be easier to just transform the vector into view space.

    For surface shaders, you can get the tangent vector by adding using:
    half3 worldTangent = WorldNormalVector(half3(1,0,0));

    For vertex fragment shader in the vertex function you can access the object space tangent directly with appdata_full and v.tangent, and transform into world space with:
    half3 worldTangent = UnityObjectToWorldDir(v.tangent);

    Then transform it into view space like this:

    half3 viewTangent = mul((float3x3) UNITY_MATRIX_V, worldTangent);

    then:

    float angleRad = atan2(viewTangent.y, viewTangent.x);
     
  3. Emiliana_vt

    Emiliana_vt

    Joined:
    Apr 7, 2018
    Posts:
    13
    Thank you so much! This is just perfect!