Waterline Demo
How to create a WebGL using Three.js, asscroll, and Midjourney AI
This simple WebGL demo utilizes the Three.js library to create a captivating waterline effect. It explores alternative mechanics for the native scroll bar, offering a unique and speculative approach.
Table of Contents
Installing libraries
For this demo, we will be using the following libraries:
asscroll
is used to create a custom scroll bar. It is a
lightweight library that is easy to use and configure.
Three.js
will help us with adding a shader effect
for the background and for the custom scroll bar.
Installing dependencies:
Adding custom scroll
The first step is to add the custom scroll bar. This is done by
creating a new instance of asscroll
and passing in the element
that will be scrolled. In this case, we will be scrolling the entire
page, so we will pass in the
document.body
element.
Note that we have disabled the requestAnimationFrame loop by setting
the disableRaf
option to true
. This is
because we will be using the Three.js requestAnimationFrame loop
instead in index.webgl.js
. That way, we can have more
control over the animation and be sure that the custom scroll bar
and the Three.js scene are in sync. We will also be using the
ease
option set to 0.22
to make the scroll animation
smoother but not too smooth. Finally, we will be disabling the default
scroll bar styles by setting the scroll barStyles
option
to false
. This is because we will be creating our own
custom scroll bar styles using WebGL.
Next, we need to add the custom scroll bar. This is done by calling
the add()
method on the asscroll
instance.
This method accepts an object of options. The only required option is
the root
property, which is the element that will be scrolled.
In this case, we will pass in the
document.body
element.
You can find the source code for the custom scroll bar module here .
Creating the scene
Creating the scene for this project is similar to the typical Three.js setup. You can take a look at the code using this link .
Please note that I'm using a simple env module when creating the scene to get some of the environment variables like viewport resolution, viewport aspect ratio, etc.
Creating the background effect
The background effect is created using a shader. You can find the source code for the shader here .
The shader is applied to a plane geometry. The plane geometry is then added to the scene.
For the background texture I used a jpg image generated with Midjourney.
The shader is applied to a plane geometry. The plane geometry is then added to the scene.
Nothing too fancy, just a Perlin noise effect applied to the Three.js plane (Perlin noise is used very often in WebGL projects and 3D). The code of the fragment shader is here .
We are also increasing time for the noise by changing it via
uniforms to the background material in the requestAnimationFrame
loop in the main module index.webgl.js
:
Creating the custom scroll bar effect
Now making the scrollbar effect is a bit more tricky. You can find
the source code for the custom scroll bar effect in
this file
. I called it water.js
because it looks like a waterline.
The module contents is a trivial Plane and ShaderMaterial initialisation,
all magic happens in the
shader
.
After taking a glance look at the shader you may notice that we are using a displacement texture.
The displacement texture is a simple black and white image (also generated with Midjourney) that is used to displace the vertices of the plane geometry. We are passing it to the shader in water.js:
Now we can use the displacement in the shader to distort uv coordinates. That will enable a slight wave effect.
Note that we only need to get one channel from the image (red in this example) in order the displacement take the effect, that's because the image is black and white. Displacement texture is an easy technique. You basically just need an image with a textured pattern you want to have for your animation.
Making the custom scroll bar draggable
asscroll scrollbar element is draggable by default. Let's just add
cursor: grab;
and cursor: grabbing;
to its corresponding states.
Please also note the width is set to 3% to make it synced with the WebGL version. Also, I had to forcibly change some of the asscroll styles in order to make the scrollbar work wherever the user clicks within the scrollbar area and tries to drag.
Useful resources
Congratulations on completing this tutorial! Let's recap what we did:
-
Created a custom inertia scroll effect using
asscroll
. - Created a Three.js scene.
- Added a shader effect to the background using Three.js.
- Added a shader effect to the custom scroll bar.
- Made the custom scroll bar draggable.
To continue your learning journey and enhance your skills, here are some valuable resources:
Bruno Simon's Three.js Journey Course
Bruno Simon's Three.js Journey is an in-depth online course that covers various aspects of Three.js, from basics to advanced techniques. The course provides practical examples and hands-on projects to help you become proficient in creating stunning 3D visuals for the web.
Three.js Examples
Explore the official Three.js examples collection. These examples demonstrate a wide range of Three.js features and concepts, serving as a valuable resource for learning and inspiration. You can dissect the code and modify the examples to suit your projects.
The Book of Shaders
The Book of Shaders is an excellent resource for gaining a deeper understanding of computer graphics and shaders. It covers fundamental concepts and provides interactive shader examples that you can experiment with directly in your browser. This knowledge can greatly enhance your ability to create custom visual effects.
asscroll Documentation
If you're interested in implementing smooth scroll animations, the asscroll documentation is a must-read. asscroll is a JavaScript library that enables advanced scroll animations with ease. By leveraging this library, you can add captivating scrolling effects to your Three.js projects.
Continue exploring, experimenting, and applying what you've learned to your own projects. The world of web 3D and interactive graphics is vast, so keep pushing your boundaries and honing your skills. Happy coding!