[Guide] Spectacles 3 Projection Lens
FeaturedHello fellow creators!
If you ever wanted to create those cool Spectacles 3 Projection Effect you might have seen as a lens or a promo video, you are in the right place! I’ll show you how you can bring those cool effects to a Spectacles Path Template. If you have not created a Spectacles 3 Lenses in the past, I highly recommend you to check out this guide the Lens Studio team made: Lenses For Spectacles.
TLDR: If you are only interested in changing the content of the Projection Effect you can jump straight to the “Adding your own unique Projection Effect” section.
Importing Contents From Another Template Project
For this guide, we will be utilizing multiple template projects already created by Snap’s Lens Studio team and combining them together as well as adding a dash of our own twist to it.
- Download the Underwater Depth Template and open the project with the latest Lens Studio.
- Create an empty object and rename it to UnderwaterDepthTemplate (renaming is optional but good to do for organizational purposes). Place all the SceneObjects that came with the project under the UnderwaterDepthTemplate SceneObject except for the Light SceneObject.
- Right click on the UnderwaterDepthTemplate SceneObject and Select ‘Export Object’. Save the `.lso` file to your computer.
- Create a new project from the Spectacles Path Template.
- Import the `UnderwaterDepthTemplate.lso` file to your project. You can do this by dragging the file in the folder you saved it in and drag it to the `Objects` Panel.
Remove Unnecessary SceneObjects and Components from LSO
There are some SceneObjects and Componentsfrom the `UnderwaterDepthTemplate.lso` that aren’t necessary so let’s remove them from the `Objects` Panel.
- Since the `Spectacles Path` Template already has a device tracker, remove the `Device Tracking` Component from the `Caustics Camera` SceneObject.
- We will also not be using the `Post-Processing Camera` SceneObject, so remove that as well.
- Let’s also disable the SceneObjects that come with the Spectacles Path Template, so that we can focus only on the Projection behavior for the time being.
Your `Preview` Panel will drastically change from a blue hue to a white caustic look.
Setting Project for Projection Effect
- To make our project a little bit more read-able, change the name of the `Caustic Camera` SceneObject to `Projection Camera`.
- Create a new layer called `Projection Layer` and assign it to the `Camera` Component of the `ProjectionCamera` SceneObject. All of our Projection Effects will have this layer and it will help us isolate any objects we don’t want the Projection Effects to be applied to.
In that same `Camera` Component change the far plane to be 10,000. This will increase the distance in which the camera will render content. - Find the `Caustics Sphere Output` Render Target and rename it to `Projection Output`. We want to do this for the same reason as step 1 of this section.
- Place both the `ProjectionCamera` SceneObject and `Caustic Sphere` SceneObject as a child of the `Camera` SceneObject that came with the Spectacles Path Template. Because the `Camera` SceneObject has a `World Device Tracking` Component, it will guarantee that the `ProjectionCamera` as well as the Caustic Sphere will follow the movements made by the parented SceneObject. Make sure the transforms for both the `Projection Camera` and `Caustics Sphere` are zeroed out.
- Make sure your `Caustic Sphere` SceneObject’s Layer is set to “Projection Layer”. You may notice that the white Caustics in the `Preview` Panel disappeared. Don’t worry we will bring it back in a transformed state, pinky promise!
- Create a new `ScreenImage` SceneObject and rename it to `ProjectionImage`. This object will be responsible for displaying our Projection Effect.
In addition, make sure the newly created `ScreenImage` SceneObject has its component set to “Stretch”. This will ensure that the Projection Effect will apply to the entire screen.
- Add the `Depth Displacement` Material to the `ProjectionImage`. This material will be responsible for applying the Projection Effect to any content that is visible by the `Projection Camera`.
- The caustic will look a bit washed out with the current Blend Mode. Change the Blend Mode to `Normal`.
- Go to the `Scene Config`. Make sure the `Render Order` is set to the following order: Projection Camera, Orthographic Camera, Camera. This will guarantee that the Projection effect will always be rendered before content that doesn’t need that effect.
Applying a Rotation Behavior to the Projection Effect
Having a static Projection Effect is a little boring. Let’s add some movement to it!
- Create an empty Child SceneObject and place it under the `Projection Camera`. Name this SceneObject as `RotationBasedMovement`. Put the `Caustics Sphere` SceneObject as a child of the `RotationBasedMovement`.
- Create a new script and name it `RotationBasedMovement`. Copy the following code snippet to the script with the Script Editor Panel.
// -----JS CODE-----
// @input SceneObject camera
var camera = script.camera;
var cameraTransform = camera.getTransform()
var worldSphere = script.getSceneObject();
var worldSphereTransform = worldSphere.getTransform();
// @input bool EnableRotation = true
// @input float rotationMultiplier = 0.01
var rotationMultiplier = script.rotationMultiplier;
var prevCamPos = cameraTransform.getWorldPosition();
var frameCounter = 0;
var isFirstFrameProcessed = false;
var currentSphereRotation = cameraTransform.getWorldRotation().invert()
script.createEvent("UpdateEvent").bind(function () {
if(!script.EnableRotation)
{
return;
}
frameCounter++;
var camPos = cameraTransform.getWorldPosition();
worldSphereTransform.setWorldPosition(camPos);
var moveVec = camPos.sub(prevCamPos);
moveVec.y = 0;
var rotAxis = vecMult(new vec3(0, 1, 0), moveVec).normalize();
var moveDistance = camPos.distance(prevCamPos);
var addAngle = moveDistance * rotationMultiplier;
var addRot = quat.angleAxis(addAngle, rotAxis);
if (isNaN(addRot.x)) {
return;
}
if (!isFirstFrameProcessed) {
isFirstFrameProcessed = true
}
currentSphereRotation = addRot.multiply(currentSphereRotation);
worldSphereTransform.setWorldRotation(currentSphereRotation);
prevCamPos = camPos;
});
function vecMult(a, b) {
return new vec3(a.y * b.z - a.z * b.y, (a.z * b.x - a.x * b.z), a.x * b.y - a.y * b.x);
}
function quatMult(a, b) {
var angle = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;
var axis = new vec3(
a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w
);
return quat.angleAxis(angle, axis);
} -
Apply the script to the `RotationBasedMovement` SceneObject. And add the `Camera` SceneObject to the camera variable of the script.
- Although subtle, you will notice the caustic now looks a bit more organic.
- Lastly, since we did build this on top of the Spectacles Path Template, let’s add those back in by enabling the three SceneObject we disabled before.
Adding your own unique Projection Effect [OPTIONAL]
You can also add your own cool Projection Effect as well! I found that the Particle System is very handy to give a nice Projection Effect. However you can add any sort of object, whether it is a 2d Image, 3D model with animation, or Particle System as long as it can be read by the camera. I added some samples using the particle system to the project that you can use as a jumping off point, but I encourage you to make your own unique creation and play around with it! Just make sure to follow the steps below
- Make sure that the layer of the object you are trying to give the Projection Effect has the “Projection Layer” applied to it. If you want the rotation behavior you can put the SceneObject as a child of the `RotationBasedMovement` SceneObject. If you don’t want the rotation behavior, set the SceneObject as a child of the `Projection Camera`.
Cheers!
----------
Download the finished project here.
Very detailed tutorial! Thank you very much Shin Kang :D
Cheers,
SirQu3ntin
Thank you very much Shin Kang
Thanks Shin .
Thanks Shin kang👍🏻👍🏻👍🏻👍🏻
Thank you very much Shin Kang