Skip to main content
Version: 5.x
Supported on
Snapchat
Camera Kit

Ocean Tool

The Ocean Tool brings a realistic ocean to your Lens! This tool offers a range of features, including a dynamic wave simulation system, interaction using touch input, body segmentation to submerge the user, and objects floating on the water's surface. Additionally, you can create an immersive split-view waterline that shows the underwater environment and the surface above, just like when you are diving in real life!

This Ocean Tool asset can be found on the Asset Library for Lens Studio 5.4.0+.

How It Works

  1. The Ocean Surface Properties material creates a noise and normal texture and draws them to the Ocean Normal and Ocean Heightmap render targets. When Touch Input is enabled under the Ocean Tool script, an additional fluid normal texture is also applied to the Ocean Normal render target.
  1. The Ocean Tool script assigns Ocean Heightmap and Ocean Normal render targets to the Ocean Surface shader. This shader then uses the heightmap to adjust its position in the vertex shader, and applies the normal texture in a PBR node for lighting.
  1. When Float Objects is enabled, the Ocean Tool script also assigns the Ocean Heightmap to all shaders associated with the scene objects listed in the Objects For Float array. The shaders then adjust each object’s height to match the ocean.

  1. When Split View is enabled, a screen space mask is drawn to distinguish areas above and below the water; if Water Line is enabled, it draws a line between the ocean’s surface and depths. The world ocean position is retrieved from the depth render target, allowing the identification of where the camera's near plane intersects the ocean and sampling of the Ocean Heightmap along the intersection.

  1. Enabling Touch Input allows the user to push the water around by tapping on the screen. This creates an additional displacement texture which is sent to the Ocean Surface, Split View, and all materials assigned to meshes under the Float Objects.

Tips

Try adding Device Tracking component under the camera with world tracking, and switch to interactive preview or the Back Camera. You can also experiment with different environment map textures or rotate the environment map to give the ocean a different look.

To make more objects float, you will need a specific graph setup to receive corresponding uniform values; duplicate the Floaty Material [COPY ME] example asset to start. If you are using a custom material, you could simply copy the part of the graph that gets values from the script, and use it in your own shader.

Controls

All available controls are under the Ocean Tool Script:

Group                                 Parameter                               Description
Ocean CameraAssign the main camera for the project. This controls the main near plane and is used to calculate world space touch position when Touch Input is enabled.
Ocean MeshThe mesh for the ocean plane; a higher poly count creates more details on the surface and split line.
Infinite OceanWhen enabled, the ocean plane will be set to the Ocean Camera position, and ocean surface UVs scroll depending on camera position. This option is only useful when world device tracking is used, as it prevents moving out of the ocean plane, and creates an illusion of an infinite world.
TransformOcean HeightThe height of the water surface.
Ocean ScaleOverall scale of the ocean plane. A good value to start with will be around 2 - 15 with the given default ocean mesh.
ColorEnable FoamAdds noise onto the crest of the ocean.
Foam ScaleThe noise scale of the foam pattern. The larger the number the more the pattern repeats (visually appears smaller).
CrestThe color of the highest point on a wave.
MiddleThe color of the middle point on a wave.
TroughThe color of the lowest point on a wave.
Reflection TextureWater reflection, usually a screen texture.
Distortion TextureSurface reflection distortion; the R and G channel of this texture will be used as a UV offset to distort the reflection texture like a flow map.
Distortion ScaleSize of the distortion texture.
Distortion IntensityDistortion weight.
DisplacementAmplitudeThe maximum vertical distance the ocean oscillates from its lowest (resting) point.
ChoppinessHigher numbers create smaller and rougher waves.
Normal StepsDetail level of the generated normal map.
Noise StepsDetail level of the generated displacement map.
Noise ScaleSize of the wave pattern.
SpeedSpeed of the wave animation.
Animation OffsetFrame offset of the ocean animation.
Body IntersectionBody Depth TextureWhen enabled, it compares view space body depth with view space ocean depth, and sorts the body intersection accordingly. When disabled, the camera texture will always be in the background.
Float ObjectsObjects For FloatThe script sets material parameters to objects assigned below to control their vertex position, it offsets the position based on wave height at where the object is in space.
Split ViewSplit ViewCalculate where the camera near plan intersects with the ocean surface; multiplies color onto the screen texture when it’s below the water level.
Camera NearCamera near clipping plane; determines where the split will be drawn.
Underwater BlurBlur factor of the underwater section.
Underwater TintColor that will be multiplied onto the screen texture underwater.
Water LineWater LineDraws a line along the water split surface.
Line ThicknessThickness of the water line.
Line TintColor of the water line.
Depth TargetThe depth value of the ocean surface will be drawn here, the shader utilized this info to retrieve the world position of the ocean to calculate its intersection with the camera’s near plane.
Touch InputTouch InputEnable touch interaction input. An additional texture will be added to the ocean displacement calculation, based on world space touch position.
Fluid IntensityTouch input value multiplier.
AdvancedHeightmap QualityResolution level of the displacement map.
Normal QualityResolution level of the normal map.

Optimization

Performance impacts

While the ocean may run perfectly in Lens Studio, you might encounter performance issues when viewing the results on different devices. This table offers an overview of how each setting can impact your Lens FPS, along with suggestions for optimizing them. The rule of thumb is to start with the lowest setting and gradually add features back in.

Impact                      Ocean Script Parameter                                  Impact Notes
🟠 MediumOcean MeshUsing a plane with a lower poly count helps reduce lens size and FPS.
🟢 LowInfinite OceanYou might not need this at all if camera tracking is not used.
🟢 LowOcean ScaleIf the ocean plane scale is larger, you might need to amp up other parameters to compensate for the texture detail. This parameter itself might not have much impact on the performance, but the compensations you make might (e.g. increasing the texture quality).
🟢 LowEnable FoamFoam is created by simplex FBM noise. It adds a fine touch on the crest of the waves; if this doesn’t improve the visual quality of the ocean in your project, you may want to leave it disabled.
🟠 MediumNormal StepsHow many loop steps to draw the normal map; it’s best to find the lowest number with acceptable visual quality.
🟠 MediumNoise StepsSame as above.
🔴 HighBody Depth TextureBody Depth Texture has a big impact on FPS on some Android devices; disable if not used or create a device blacklist.
🟢 LowFloat ObjectsExtra materials and scene objects in the project can all contribute to larger Lens size.
🟢 LowSplit ViewDepth Render Target and an extra post effect will be used. This should be disabled if your camera never sees what’s below the ocean surface and device tracking is not used.
🔴 HighTouch InputAn advanced feature that draws fluid touch position onto multiple render targets in the background.
🟢 LowHeightmap QualityResolution of the displacement map. Consider setting it to Low if the visual quality is acceptable.
🟢 LowNormal QualitySame as above.

Troubleshooting

General

Nothing happens when I import the asset?

  • Check if the Ocean Camera under the Ocean Tool Script is assigned to the camera you are currently viewing.
  • Ensure that your Capture Target under the Asset Browser -> Scene is the same as the render target used for the camera
  • Check the Logger window to see if there are any error hints.

Ocean color is not consistent on device compared to what I see in Lens Studio.

It’s most likely because the reflection is reading from the screen texture. In Lens Studio, the reflection color you see comes from the preview video or image. However, in real environments, the color can vary dramatically. Try using a static image for the Reflection Texture input under the Ocean Tool Script instead. Doing this may result in the loss of dynamic lighting, meaning the ocean surface will no longer reflect based on your real environment, but it can help ensure the color stays consistent.

How can I redefine the color based on the ocean height?

The ocean height color is controlled using a Gradient node in the Ocean Surface material, located in the Albedo section and highlighted with a green comment box.

Floating Objects

The floating object doesn’t follow the ocean wave.

If the mesh's pivot point is not centered, you will need to adjust it in a third-party app and then reimport the mesh into Lens Studio. This tool adjusts the 3D mesh to flow on top of the ocean by setting its vertex position to match the height of the ocean surface. Therefore, avoid modifying the Y transform of your 3D object to fit the water height, as this can interfere with the vertex animation. To control how deep your floating object sinks into the water, set its Y transform to 0, or close to 0, based on your preference.

How can I make my floating objects bob more/less?

Go to the shader graph assigned onto your floating object; the custom code node titled Vertex Position Offset From Ocean highlighted with a green comment box has additional speed and amount controls.

Split Line

I can’t see the split line, it zooms past the camera view too fast.

Try pushing back your Camera Near value, or widen your camera FOV; it’s likely the camera is too close when the ocean plane is too large.

The edge of the split view ocean plane looks low poly.

Consider setting the Camera Near further away, adjusting Line Thickness to hide the edge, or lowering the Ocean Scale.

How can I get a black and white split mask from the split view?

Go to Split View shader, under the custom code node you can output the split value. This texture can be useful if you want to use this mask as an occluder.

Was this page helpful?
Yes
No