
Say you want to display a few key locations on your globe—points you can interact with to display some sort of extra data such as population. Getting those points onto your sphere in the correct spots requires a bit of geometry and trigonometry magic.
In this tutorial, I'll show you how to perfectly place Three.js spheres on your globe using the world's accepted latitude and longitudinal coordinate system.
Some of you may have noticed, even though a hard refresh always gives our canvas the correct dimensions, a normal refresh sometimes shoves our canvas towards the top right-hand corner of the screen, shrinking it in the process.
Although not a deal breaker, it is quite an annoying effect to develop with, so before we go any further we'll go ahead and fix it.
This issue is caused by loading tailwind.css directly within our Vite's index.html file. When developing with Vite, the bundler performs some caching magic behind the scenes, running our JavaScript before completely loading a big file like Tailwind.css. Although this is useful for instant JavaScript updates, it obviously provides the issue of shrinking our canvas when it is reliant on some Tailwind classes meant to maintain its width and height.
We can fix this by simply commenting out the <link> tag importing Tailwind within index.html, and importing ./tailwind.css within main.js.
Another bug you may have come across also occurs on page refresh—whenever we refresh our page, the globe doesn't show initially, it only shows as soon as we begin to move our mouse.
This occurs due to our use of gsap.to(). If you look at what we are setting our globe group's x and y rotation equal to, you'll see we're assigning them values that are calculated based off our mouse's x and y properties. Whenever we refresh the page, these mouse x and y properties are initialized as undefined. If we try setting our globe group's rotation value to something like undefined, well, the globe won't render, thus we get the issue where there's nothing to show initially.
To fix this, all we need to do is set our mouse's x and y property to something other than undefined to start, or we need to wrap our gsap.to() function in a conditional that checks for mouse.x or mouse.y to be set.
Our points are currently displayed as spheres using Three.js' SphereGeometry object, however, this could potentially limit our ability to display some sort of useful data attribute based on the size of our geometry. It would make more sense to change our SphereGeometry to a BoxGeometry, affecting the individual geometries height so that they're easily differentiated from one another when representing some sort of data.
Although you may think it's as simple as swapping out our geometry object type, you'll quickly realize that doing so creates for an awkward effect where rectangular geometries are placed on the globe without any rotation.
To alleviate this, we'll be using Three.js' lookAt method on top of our geometry. Finally, we'll translate our newly created rectangular prisms using a Matrix4 (an array with four rows and columns that represents how an object should be moved in 3D space).
Adding a touch of animation can go a long way towards impressing any visitors who come across your website. Rather than leave our point boxes static on our globe, we'll animate their z scale to create an effect as if the boxes are growing, then receding over time using GSAP and it's option properties.
I'll also cover some quick code maintenance best practices while changing the color of our current boxes from red to teal.
Our animated boxes look nice, but they're kind of useless if they're not displaying or representing any sort of data.
In this episode, I'll show you how to create an HTML label that displays the population for each country we've added so far whenever you hover over one its associated boxes.
Let's face it, populating a globe manually by calling createBox over and over again is quite tiresome. Rather than calling a function multiple times and inserting data by hand, we can create a bulk insert function that takes data from a comprehensive source, and parses it into boxes that are automatically placed on our globe.
It's no doubt, a bit hard to hover over and view our country data while the globe (and everything attached to it) is spinning merrily along. A good solution to this: stop the automatic spinning, and implement a click and drag functionality.
Here we'll cover the theory behind creating a click and drag function, then implement it using a few new event listeners, something called delta, and a GSAP animation function.
The globe looks and functions great, but it definitely has some issues when scaling down the browser window. The first is, the globe won't stay centered in the middle of the canvas when shrinking down the window on larger screen sizes. The second is, once we get to mobile screen sizes, there's not enough room for our globe to fit on the screen in the first place.
This lesson will teach you how to fix both of these issues using a combination of HTML, event listeners, and Three.js. We'll match the same style used for the globe on github.com by ensuring our globe travels beneath our website's text on smaller screen sizes.
Previously, we resized our scene to fit the smaller screen proportions associated with phones and tablets. However, you may have noticed, when testing on an actual mobile device, the globe doesn't spin like it does on desktop.
In this video, we'll cover how to add mobile event listeners to our project so we can re-obtain the spin effect on mobile.
PLEASE READ: This is a freemium course—the first hour and a half are free (you can watch right here on Udemy [or YouTube] with each video's "Preview" button), while the remaining 3 hours require course purchase. I've always been a big advocate of spreading the basics to as many people as possible, as I believe knowledge and personal growth are some of the best ways to better our world as a whole. Enjoy.
Welcome to the Intermediate ThreeJS with Shaders course, where you will learn how to create an interactive 3d globe with custom ThreeJS shaders.
My name is Christopher Lis, and I'm an award winning Full-Stack Engineer with over ten years of web development experience. I've directly worked with clients like Harvard University, The Basketball Tournament, and premium award winning agencies like Brave People.
The goal of this course is to get you writing your own custom ThreeJS shaders with GLSL, and to help you understand how to import these shaders into a practical ThreeJS scene. You'll also learn how to dynamically place data points on a globe based on the latitude and longitude of different countries. There are little to no videos out there that actually go into this topic in-depth so I figured I should tackle it.
In this course, you'll learn everything from:
- Vertex Shaders
- Fragment Shaders
- Import Shaders with Vite Plugins
- Normals
- Uniforms
- Attributes
- Varyings
- Point clouds and particles
- Bulk Data Imports
- Rectangular Mesh Animation
- Click and Drag Functionality
- Scene Responsiveness
- Touch Event Listeners
And so much more.
If you're serious about taking your ThreeJS skills to the next level, then shaders are logically the next step after become acquainted with the framework. Let me guide you through the full production of a 3d scene you can actually use for a real website.