Getting Started with Lens Studio
By: Jared Alexander
Tags: Tutorial, Lens Studio, Augmented Reality

We’ve all either come across or used apps that apply fun filters to our photos, whether we are creating our own, or viewing someone else’s feed. But how are these made? Yes, I understand how to use Facebook/Instagram/Snapchat/<insert trendy social app here>. What I really mean is: how do software developers create these amazing filter experiences for us to play with? In this tutorial, we’ll focus on a single filter platform called Lens Studio, created by Snapchat, Inc. You can download it here.

We’ll be making enhancements to an existing template provided by Lens Studio called Team Celebrate. Here is the end result:

My filter is UVA focused, but you’ll customize yours for your school and/or favorite sports team!

Setting up your project

Open Lens Studio, use the search bar to search for a template named Team Celebrate, and click to open it.

2. The lens will load, and you’ll instantly see it working on the right-hand side of the screen. You can try out different still images and video loops by using the drop-down menu in the middle, above the video loop. Feel free to experiment with different images and videos to see how the effect looks.

3. But you aren’t here to see the filter effect on other people! To try it out on yourself, click the Webcam Preview button (note that I experienced issues with external web cams, so try your built-in one first). Alternatively, you can send it to your own Snapchat account by clicking “Preview in Snapchat” in the top right-hand corner.

4. To customize the filter, click TeamCelebrateController [EDIT_ME] in the Objects browser in the top left-hand corner. You can customize colors, effects, show/hide different effects, and even replace the logo and banner images! Go ahead and spend some time customizing it for your school colors.

5. Let’s take a moment to save your project. Click File->Save As and name it My Team Celebrate.

6. For Team Logo and Team Banner, you’ll need to obtain your own images from the web. Click here to jump to a Google Image search for .png images with transparent backgrounds. Replace the search for <your college> logo. Download the image, and rename it to something sensible (e.g. uva-logo.png). Rinse and repeat for a banner image - for this, feel free to find an alternate image that might represent your school’s mascot or motto. Drag these two images into the Resources browser under the Example Resources [REMOVE ME] folder.

7. Click your TeamCelebrateController [EDIT_ME] in the Objects browser and select your custom Team Logo and Team Banner (under Screen Banner) in the Inspector to update your Preview window.

8. You’ll notice that the team banner image I selected is way too big and there is no way to scale it down via the TeamCelebrateController properties (though you can scale the logo). We can fix that. In the Resources browser, click the Scripts->TeamCelebrateController [EDIT_ME] to edit the file’s code. Add the following line to the Screen Banner widget group:

// @input float bannerSize = 0.3 {"showIf":"showBanner", "widget":"slider", "min":0.0, "max":1.0, "step":0.01}

9. Additionally in this file, find the configureScreenBanner() function, add the following lines to the end of the if {} block:

var size = new vec2(script.bannerSize, script.bannerSize).uniformScale(2.0); setRectSize(screenTransform.anchors, size);

Click File->Save.

Note: You may see the following error in the Logger at the bottom, but I’ve found it can be safely ignored and eventually goes away:

Argument 0: Value is not a number

The bannerSize property is now available to tweak in the Inspector when clicking TeamCelebrateController [EDIT_ME] in the Objects browser!

10. You’ll notice your eyes look a bit funky — the template we selected is applying some Face Effects. Feel free to disable these by deselecting the Face Effects under Camera->Effects->Face Effects in the Objects browser.

11. The goal of the rest of this tutorial is to customize this lens to add a few enhancements:

Upon tapping the screen, randomly cycle through the different Face Paint Types

Instead of confetti constantly dropping, modify the filter’s behavior to only show confetti when you open your mouth.

Add a virtual background from your school’s campus — this could be your favorite building, sports arena, or maybe even your dorm!

Tip: If you are ever missing the Object browser, Resources Browser, Inspector, etc.., you can always reset the layout by going to Window->Panels->Default Layout.

Pick a random face paint type upon tapping the screen

1. Click the Scripts->TeamCelebrateController in the Resources browser to edit its code.

2. Update the function signature of configureFacePaint() to look like this:

function configureFacePaint(isRandom) {

3. Modify this configureFacePaint() function’s code for loop that iterates through the facePaintTypes, add logic to that will pick a random or single selected facePaintType based on whether isRandom is passed into the function. Here is the code snippet to inject into that function:

script.facePaintType = isRandom ? Math.floor(Math.random() * script.properties.api.facePaintTypes.length) : script.facePaintType;

4. Next, add an additional function right above configureFacePaint(isRandom) which will allow us to access the function outside this file:

script.api.configureFacePaint = function(isRandom) { configureFacePaint(isRandom); }

Click File->Save.

5. In the Resources browser, click the + to add another new Script and rename it TapController. Move it into the Scripts folder, if it isn’t already there.

Add the following code:

//@input Component.ScriptComponent TeamCelebrateController script.TeamCelebrateController.api.configureFacePaint(true);

Click File->Save.

6. Click TeamCelebrateController [EDIT_ME] in the Objects browser, and in the Inspector window, click Add Script and choose TapController

Map this script to the Tapped event.

7. You’ll now find a new property at the bottom of your TeamCelebrateController’s Inspector called Team Celebrate Controller. Set that to TeamCelebrateController [EDIT_ME].

8. Now try tapping the screen — you should see the face paint change each time to a random type!

Trigger confetti via the Mouth Opened facial gesture

1. Click TeamCelebrateController [EDIT_ME] in the Resources browser to edit the file’s code.

2. Inside the init() function, remove the call to configureConfetti() and add this line

script.properties.api.confetti.enabled = false;

3. Modify the configureConfetti() function signature to look like this:

script.api.configureConfetti = function(on) {

4. Update the first line of this function to add a check for the on boolean in the if statement:

if (script.properties.api.confetti && on) {

5. Add an else clause to the end of the function — this will be directly after the closing of the if statement that starts on the first line of the configureConfetti() function.:

else { script.properties.api.confetti.enabled = false; }

6. In the Resources browser, click the + to add a new Script and rename it StartConfettiController. Move it into the Scripts folder if it isn’t already there.

Add the following code to your newly created StartConfettiController:

//@input Component.ScriptComponent TeamCelebrateController script.TeamCelebrateController.api.configureConfetti(true);

Click File->Save.

7. In the Resources browser, click the + to add another new Script and rename it StopConfettiController. Move it into the Scripts folder if it isn’t already there.

Add the following code to your newly created StopConfettiController:

//@input Component.ScriptComponent TeamCelebrateController script.TeamCelebrateController.api.configureConfetti(false);

Click File->Save.

8. In the Objects browser, click TeamCelebrateController [EDIT_ME] and review the Inspector. Click Add Script and choose your StartConfettiController.

Repeat for the StopConfettiController, and map them to the Mouth Opened and Mouth Closed events, respectively.

9. Test out your changes in the Preview window — opening your mouth should trigger confetti and closing your mouth should stop it.

Tip: If it doesn’t seem to be working, try clicking the Reset Lens button in the Preview pane:

Adding a virtual background

Find an image online (or use one that you’ve taken!) to use as your virtual background, and name it something sensible (e.g. uva-background.jpg). Drag it into the Example Resources [REMOVE_ME] folder in the Resources browser in the bottom left-hand corner. Also, in the Resources browser, click the + to add a Simple PBR Material. Make sure to drag this into the Materials folder, and rename it to virtual_background.

3. In the Inspector on the right-hand side:

update Base Texture->Texture to your virtual background image file

uncheck the Lighting checkbox

4. Next, in the Resources browser:

click the + to add a Segmentation Texture->Portrait Background

move this into the Textures folder.

5. Additionally in the Resources browser:

add a new Render Target by clicking +, and choosing Render Target

rename this to Virtual Background Render Target

move it under the Textures folder

6. In the Objects browser in the top left-hand corner:

click + to add another Camera

rename it to VirtualBackgroundCamera

7. With VirtualBackgroundCamera selected in the Objects Browser, let’s modify values in the Inspector:

set the Camera Type property to Orthographic

set the Mask Texture to Portrait Background Segmentation

set its Render Target property to Virtual Background Render Target.

click into the Layers box and choose Add New Layer, and create a new layer and rename it Virtual Background — *this should be the only layer selected*.

8. Still in the Objects browser, with VirtualBackgroundCamera selected:

click + to add an Image Object

9. Modify the Image Object’s properties in the Inspector:

set Material to your virtual_background material

set Stretch Mode to Fill.

set its Z position to -1.0

set its layer to Virtual Background

10. Click the Camera (not the Virtual Background Camera) in the Objects browser, and in the Inspector:

set its Clear Color Option to Texture

set its Input to Virtual Background Render Target

11. Back in the Resources browser under Textures:

find the existing Render Target

Render Target set its Texture->Clear Color property to None in the Inspector.

Tip: I’ve noticed different behavior in Lens Studio (different laptops) upon setting the Clear Color property to None vs Background. If None doesn’t work, try Background.

Voila, you should now have your image as the virtual background!

What’s Next?

I hope you enjoyed enhancing the team celebration template to make it more interesting and interactive! While I think it’d be neat to publish what you’ve made, please be mindful of any copyrights and/or trademarks of the imagery you’ve selected.

I encourage you to continue learning by following the numerous Lens Studio Guides published by Snapchat. Have fun!