The position of the vertices relative to the normal

In the surface shader, given the world axis (and others), the place in the world space and the normal in the world space, how can we turn the position of the world space into a normal space?

That is, taking into account the age vector and non-orthogonal goal vector, how can we transform the position by turning its vector up?

I need this so that I can get the vertex position affected only by the rotation matrix of the object, to which I do not have access.

Here's a graphical visualization of what I want to do:

  • Up is a vector up.
  • The goal is normal space in the world
  • Pos randomly

The chart is two-dimensional, but I need to solve it for 3D space.

vector diagram

+4
2

, pos , new_up.

, pos, . , :

// Our 3 vectors
float3 pos;
float3 new_up;
float3 up = float3(0,1,0);

// Build the rotation matrix using notation from the link above
float3 v = cross(up, new_up);
float s = length(v);  // Sine of the angle
float c = dot(up, new_up); // Cosine of the angle
float3x3 VX = float3x3 (
    0, -1 * v.z, v.y,
    v.z, 0, -1 * v.x,
    -1 * v.y, v.x, 0
); // This is the skew-symmetric cross-product matrix of v
float3x3 I = float3x3 (
    1, 0, 0,
    0, 1, 0,
    0, 0, 1
); // The identity matrix
float 3x3 R = I + VX + mul(VX, VX) * (1 - c)/pow(s,2) // The rotation matrix! YAY!

// Finally we rotate
float3 new_pos = mul(R, pos);

, new_up .

"target up normal" , R ( ) . . / , , .

pos -4, , ( ).

, , , - , , .

0

, point axis. , , procession, (0-1) , .

using UnityEngine;
using System.Collections;

public class Follower : MonoBehaviour {

    Vector3 point;
    Vector3 origin = Vector3.zero;
    Vector3 axis = Vector3.forward;
    float distance;
    Vector3 direction;
    float procession = 0f;  // < normalized

    void Update() {
        Vector3 offset = point - origin;

        distance = offset.magnitude;
        direction = offset.normalized;

        float circumference = 2 * Mathf.PI * distance;

        angle = (procession % 1f) * circumference;

        direction *= Quaternion.AngleAxis(Mathf.Rad2Deg * angle, axis);
        Ray ray = new Ray(origin, direction);

        point = ray.GetPoint(distance);
    }
}
-2

All Articles