Search Unity

Problem with lookAt vertex shader / model space

Discussion in 'Shaders' started by GearKlik, Feb 9, 2016.

  1. GearKlik

    GearKlik

    Joined:
    Sep 21, 2015
    Posts:
    58
    Hi all, I'm trying to write an unlit shader that make each "particle" (a quad I've generated with a component with random RGBA vertex colors) look at the camera. My code works if the game object is at world zero but not if the transforms are touched. There seems to be something wrong with my space conversion.

    I've seen these posts:
    http://answers.unity3d.com/questions/745308/-worldspacecamerapos-and-converting-to-object-spac.html
    http://answers.unity3d.com/questions/282867/unity-shader-worldobject-matrix-1.html

    But nothing is working for me. Plus they are for Unity 4.

    This is my thought process:
    1. Each quad is 1 x 1 units in size and centered at local zero. This all works fine.
    2. All the vertices of the same quad are given the same random colors in RGBA vertex color. This all works fine.
    3. Get the world space center of the quad
    4. Get a vector between world space center of the quad and the world space camera position
    5. Create and apply a lookAt matrix.
    6. Offset the quads position in local space.
    7 Apply MVP matrix.

    Code (CSharp):
    1. v2f vert (appdata v)
    2.             {
    3.                 v2f o;
    4.  
    5.                 float4 localSpaceVert = v.vertex;
    6.                 float4 debiasedColor = (v.color  * 2.0) - 1.0;  // v.color = float4(randomNumber(0-1), randomNumber(0-1), randomNumber(0-1), randomNumber(0-1))
    7.  
    8.                 // Local space particle position
    9.                 float3 localSpaceParticlePos = debiasedColor * _ParticleBounds; // default = float3(1,1,1)
    10.                
    11.                 // Get world space position of particle
    12.                 float3 worldSpaceParticlePos = mul(_Object2World, localSpaceParticlePos);
    13.  
    14.                 // Get particle - camera vector
    15.                 float3 camVect = normalize(worldSpaceParticlePos - _WorldSpaceCameraPos);
    16.                
    17.                 float3 up = float3(0, 1, 0);
    18.  
    19.                 // Create LookAt matrix
    20.                 float3 zaxis = camVect;
    21.                 float3 xaxis = normalize(cross(up, zaxis));
    22.                 float3 yaxis = cross(zaxis, xaxis);
    23.  
    24.                 float4x4 lookatMatrix = {
    25.                     xaxis.x,            yaxis.x,            zaxis.x,       0,
    26.                     xaxis.y,            yaxis.y,            zaxis.y,       0,
    27.                     xaxis.z,            yaxis.z,            zaxis.z,       0,
    28.                     0, 0, 0,  1
    29.                 };
    30.  
    31.                 // Apply LookAt matrix
    32.                 localSpaceVert = mul(lookatMatrix, localSpaceVert);
    33.  
    34.                 // Apply local particle position offset
    35.                 localSpaceVert.xyz += localSpaceParticlePos.xyz;
    36.  
    37.  
    38.                 // Apply MVP matrix to model
    39.                 o.vertex = mul(UNITY_MATRIX_MVP, localSpaceVert);
    40.                
    41.                 o.uv = v.uv;              
    42.                 o.color = v.color;
    43.  
    44.                 return o;
    45.             }
    Any help would be greatly appreciated :)

    TNKS!

    G
     
  2. GearKlik

    GearKlik

    Joined:
    Sep 21, 2015
    Posts:
    58
    Welp, as usual explaining this on the forum made me think of the answer. I needed to do everything in local space and I also needed to make sure _WorldSpaceCameraPos is a float4 with w = 1.

    Code (CSharp):
    1. v2f vert (appdata v)
    2.             {
    3.                 v2f o;
    4.  
    5.                 float4 localSpaceVert = v.vertex;
    6.                 float4 debiasedColor = (v.color  * 2.0) - 1.0;  // v.color = float4(randomNumber(0-1), randomNumber(0-1), randomNumber(0-1), randomNumber(0-1))
    7.  
    8.                 // Local space particle position
    9.                 float4 localSpaceParticlePos = debiasedColor * _ParticleBounds; // default = float3(1,1,1)
    10.                 localSpaceParticlePos.w = 1;
    11.                                
    12.                 // Get camera pos in local space
    13.                 float3 localSpaceCameraPos = mul(_World2Object, float4(_WorldSpaceCameraPos.xyz, 1));
    14.                
    15.                 // Get particle - camera vector
    16.                 float3 camVect = normalize(localSpaceParticlePos - localSpaceCameraPos);
    17.                
    18.                 float3 up = float3(0, 1, 0);
    19.  
    20.                 // Create LookAt matrix
    21.                 float3 zaxis = camVect;
    22.                 float3 xaxis = normalize(cross(up, zaxis));
    23.                 float3 yaxis = cross(zaxis, xaxis);
    24.  
    25.                 float4x4 lookatMatrix = {
    26.                     xaxis.x,            yaxis.x,            zaxis.x,       0,
    27.                     xaxis.y,            yaxis.y,            zaxis.y,       0,
    28.                     xaxis.z,            yaxis.z,            zaxis.z,       0,
    29.                     0, 0, 0,  1
    30.                 };
    31.                
    32.                 // Apply LookAt matrix
    33.                 localSpaceVert = mul(lookatMatrix, localSpaceVert);
    34.  
    35.                 // Apply local particle position offset
    36.                 localSpaceVert.xyz += localSpaceParticlePos.xyz;
    37.  
    38.                 // Apply MVP matrix to model
    39.                 o.vertex = mul(UNITY_MATRIX_MVP, localSpaceVert);
    40.                
    41.                 o.uv = v.uv;              
    42.                 o.color = v.color;
    43.  
    44.                 return o;
    45.             }
     
    lilacsky824, StaffanEk and Alekxss like this.