Search Unity

(Vector math) Finding opposite point over a plane for reflection probe-based mirrors

Discussion in 'Physics' started by dakotapearl, Jul 4, 2015.

  1. dakotapearl

    dakotapearl

    Joined:
    May 29, 2014
    Posts:
    21
    I'm trying to find where to place a reflection probe to get a good reflection for a player looking in a mirror and I want to do it for an arbitrarily placed mirror, but I'm having trouble with the vector math. I've more or less guessed most of it so far... Anyone feel like lending a hand?

    What I have so far is the following function which works well if the mirror is aligned with the x axis, as it rotates it goes through the mirror and eventually when the mirror is aligned with the z axis, it's on the opposite side of the mirror. I'm not sure how else to describe the purpose of this function, but if the point indicates an object and the plane, the mirror, then the return value is the virtual image of the object. It's just the opposite side of the plane to the point.

    Code (CSharp):
    1.     public Vector3 ReflectionOverPlane(Vector3 point, Plane plane) {
    2.         float distance = plane.GetDistanceToPoint(point);
    3.         Vector3 pointToClosestPointInPlane = distance * plane.normal;
    4.         return point - 2 * pointToClosestPointInPlane;
    5.     }
    I'll post the full code if anyone wants to try it. You just have to put it on a quad or plane and make sure that the material is a standard Unity 5.0 shader with full metallic and smoothness properties. It should do the rest. I'd love to know if anyone finds any other bugs too! Thanks!

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Mirror : MonoBehaviour {
    4.  
    5.     // Used for keeping track of probes
    6.     public static int UID = 0;
    7.     public static GameObject ProbeContainer;
    8.  
    9.     // Properties
    10.     public int standardResolution = 512;
    11.  
    12.     // Generated variables
    13.     private Transform characterCamera;
    14.     private Mesh mesh;
    15.     private ReflectionProbe probe;
    16.     private Plane plane;
    17.  
    18.     // Use this for initialization
    19.     void Start () {
    20.  
    21.         // Find/create probe container
    22.         if (ProbeContainer == null) {
    23.             ProbeContainer = GameObject.Find("Probes");
    24.             if (ProbeContainer == null) {
    25.                 ProbeContainer = new GameObject();
    26.                 ProbeContainer.name = "Probes";
    27.             }
    28.         }
    29.  
    30.         // Get the main camera transform
    31.         characterCamera = Camera.main.transform;
    32.  
    33.         // Get the mesh of the current object and create plane object from it
    34.         // Assuming the current objects mesh is a plane or a quad. That is that every vertex lies in the same plane
    35.         mesh = GetComponent<MeshCollider>().sharedMesh;
    36.         plane = new Plane(mesh.vertices[0] + transform.position, mesh.vertices[1] + transform.position, mesh.vertices[2] + transform.position);
    37.  
    38.         // Create a new game object with a reflection probe
    39.         probe = (new GameObject()).AddComponent<ReflectionProbe>();
    40.         probe.gameObject.name = "Probe " + ++UID + " (" + gameObject.name + ")";
    41.         probe.transform.SetParent(ProbeContainer.transform);
    42.         probe.refreshMode = UnityEngine.Rendering.ReflectionProbeRefreshMode.ViaScripting;
    43.         probe.timeSlicingMode = UnityEngine.Rendering.ReflectionProbeTimeSlicingMode.NoTimeSlicing;
    44.         probe.mode = UnityEngine.Rendering.ReflectionProbeMode.Realtime;
    45.         probe.resolution = standardResolution;
    46.         GetComponent<MeshRenderer>().probeAnchor = probe.transform;
    47.  
    48.     }
    49.  
    50.     void Update () {
    51.  
    52.         // if the character is on the rendering side of the object
    53.         if (plane.GetSide(transform.position - characterCamera.position)) {
    54.  
    55.             // Set the position to be reflected about the plane
    56.             probe.transform.position = transform.position + ReflectionOverPlane(characterCamera.position - transform.position, plane);
    57.  
    58.             // Render probe
    59.             probe.RenderProbe();
    60.  
    61.         }
    62.  
    63.     }
    64.  
    65.     public Vector3 ReflectionOverPlane(Vector3 point, Plane plane) {
    66.         float distance = plane.GetDistanceToPoint(point);
    67.         Vector3 pointToClosestPointInPlane = distance * plane.normal;
    68.         return point - 2 * pointToClosestPointInPlane;
    69.     }
    70.  
    71. }
     
  2. dakotapearl

    dakotapearl

    Joined:
    May 29, 2014
    Posts:
    21
    Figured it out with help from wikipedia!

    Code (CSharp):
    1.     public Vector3 ReflectionOverPlane(Vector3 point, Plane plane) {
    2.         Vector3 N = transform.TransformDirection(plane.normal);
    3.         return point - 2 * N * Vector3.Dot(point, N) / Vector3.Dot(N, N);
    4.     }
     
    JeremyLvChy likes this.
  3. JeremyLvChy

    JeremyLvChy

    Joined:
    Jul 23, 2019
    Posts:
    10
    Why dot(N,N),and this calc give me correct position when plane's position is (0,0,0) ,when change the plane source position ,the result is error .