I’m currently working on a Virtual Ray Tracer; a program that visualizes how ray tracing works. I added a spotlight to this program, and all works fine, except for the canvas. The existing point light had a simple solution to make the canvas look at the user:
canvas.transform.forward = (Camera.main.transform.position - Position).normalized;
Makes sense and works perfectly. (Positon returns transform.position) But unlike the pointlight, the spotlight has a direction. So now it’s important that the canvas looks in the same direction as the light. In my case, it means rotating around the x and y-axis. After that, I’d like it to rotate around the z-axis to make the canvas look toward the user as much as possible. I thought this would be as simple as rotating the canvas towards the user and then undoing rotation around x and y:
canvas.transform.up = (Camera.main.transform.position - Position).normalized;
canvas.transform.localEulerAngles = new Vector3(0, 0, canvas.transform.localEulerAngles.z);
(The default looking direction is +z, the canvas is flat in the XZ plane, so I need the top (up) to point toward the user).
I then thought that maybe I should project the light-camera vector on the spotlight’s local XY plane, set the transform.up to that. I figured that that should only rotate around the z-axis:
canvas.transform.up = Vector3.ProjectOnPlane(Camera.main.transform.position - Position, transform.forward).normalized;
This didn’t work, so I tried to set the local x and y rotation to zero again. This almost worked, but now I couldn’t see it. Adding 90 to the z worked better:
canvas.transform.up = Vector3.ProjectOnPlane(Camera.main.transform.position - Position, transform.forward).normalized;
canvas.transform.localEulerAngles = new Vector3(0, 0, canvas.transform.localEulerAngles.z + 90);
This unfortunately still is not working correctly. It works perfectly when the light is also looking in the z+ direction, but when rotated, it does not rotate correctly. I disabled the possibility for the user to rotate around the z-axis.
I tried some other stuff which I do not all remember, but nothing worked, unfortunately. I hope someone can help me with this!
The program is an open-source application (MIT License), you can find the full code of my version on GitHub.
It works with WebGL and there is a ‘working’ version here. If you enable ‘Cheat Mode’ in the settings you can skip to the level ‘Advanced Lighting - Spot Lights’ where the spotlight makes its first appearance.