In this article, you will learn to add a sticker to a texture with WebGL. In detail, you will learn how to use the Three.js JavaScript library to add an overlay image to a texture. You can learn about other image operations like resizing libraries like React here.
Dealing with 3D graphics used to be a challenging, complex, and time-consuming task. But thanks to libraries like three.js
, it has become more accessible than ever. Follow this easy step-by-step how-to and achieve this result:
Prerequisites
Here are all the prerequisites required to follow this tutorial and build the demo application shown above:
- Three.js r137 or greater
- This Three.js plugin
Learn more about how to install three.js
here.
What is Three.js?
As stated in the official GitHub page of the project, the goal of the Three.js project is to create a lightweight 3D JavaScript library with a very low level of complexity. In other words, Three.js aims to make 3D graphics more accessible, especially considering that Three.js only requires a browser to run.
To be more specific, Three.js allows you to create a 3D graphics project where you can modify elements in your browser and see visual feedback. The library is currently built on top of a WebGL renderer, but it also supports WebGPU, SVG, and CSS3D renderers.
If you are not familiar with these concepts, WebGL stands for “Web Graphics Library” and is a JavaScript API for rendering high-performance interactive 3D and 2D graphics. You can use WebGL in many web browsers without external plugins or libraries.
As you can verify here, browsers currently support the most popular WebGL features. However, keep in mind that the user’s device must meet hardware requirements for some features to work.
WebGL is undoubtedly a powerful tool. On the other hand, it takes a long time to reach a high level of skills. Plus, it involves a lot of boilerplate code. And here is where Three.js comes into play, allowing you to avoid most of these cumbersome WebGL tasks.
Now, let’s see it in action!
Adding an Overlay Image to a Texture in WebGL
Clone the GitHub repository that supports this article with the following commands:
git clone https://github.com/Tonel/how-to-add-a-sticker-with-threejs-imgly
Additionally, try the demo application by launching how-to-add-a-sticker-with-threejs-imgly/index.html
in your browser.
Otherwise, keep following this tutorial and learn how this application works.
Specifically, this is the entire JavaScript code required to achieve the goal:
// initializing the WebGL renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// initializing a Three.js scene
const scene = new THREE.Scene();
// seting up a Three.hs PerspectiveCamera + its OrbitControls
const camera = new THREE.PerspectiveCamera(
40,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set(150, 100, 150);
const controls = new THREE.OrbitControls(camera, document.body);
// adding light to the scene to make the texture visible
const light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// adding the axes helper indicator to the scene
scene.add(new THREE.AxesHelper(20));
// initializing the Three.js texteure loader
const loader = new THREE.TextureLoader();
// crating a new buffer geometry and placing it
// to the horizontal plane
var geometry = new THREE.PlaneBufferGeometry(50, 50);
geometry.rotateX(-90 * THREE.Math.DEG2RAD);
// translating the plane to the center of the scene
geometry.translate(25, 0, 25);
const texturePath =
"https://threejs.org/examples/textures/hardwood2_diffuse.jpg";
const stickerPath = "https://i.imgur.com/IYh17Rv.png";
// adding a sticker to a texture material
// with onBeforeCompile
var material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
map: loader.load(texturePath),
bumpMap: loader.load(texturePath),
onBeforeCompile: function (shader) {
// adding the sticker
// https://github.com/Fyrestar/THREE.extendMaterial#patching-shader-code
THREE.patchShader(shader, {
header: "uniform sampler2D tDecal; uniform vec4 uDecal;",
fragment: {
"#include <fog_fragment>": `
vec2 offset = uDecal.xy + vUv / uDecal.zw;
vec4 c = texture2D(tDecal, offset);
gl_FragColor = mix(gl_FragColor, c, c.a);
`
},
uniforms: {
uDecal: new THREE.Vector4(-0.15, -0.15, 0.8, 0.8),
tDecal: loader.load(stickerPath)
}
});
}
});
// adding the Three.js Mesh to the scene
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
function launchThreeJs() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
launchThreeJs();
In the first few lines, we initialize a Three.js Scene
. This allows you to define what and where three.js
will render. Then, we add a PerspectiveCamera
with OrbitsControl
to the scene to move around. Similarly, the scene is lit by an AmbientLight
instance, which takes care of illuminating all objects in the scene equally.
Finally, we create a horizontal plane with PlaneGeometry
. This is employed a few lines below to place the texture and its sticker, thanks to MeshPhongMaterial
. This particular function allows you to create a material for shiny surfaces and specular highlights.
In detail, the magic required to add an overlay image to a texture happens in onBeforeCompile
. Here, the THREE.patchShader
helper plugin comes into play, allowing you to place an image patch over the original texture with just a few lines of GLSL code. Learn more on how to use this plugin in this thread from the official Three.js forum.
Et voilà! You just learned how to add a sticker to a WebGL texture with three.js
!
Adding a Sticker With PHOTOEDITORSDK
PhotoEditorSDK uses WebGL as the main renderer. You can effortlessly add a sticker to your textures without writing any line of code. WebGL will be used behind the scene. Consequently, you do not need to know WebGL or code in GLSL to harness its power.
Adding a sticker to an image only takes a few seconds here. Just jump to this article from the official documentation and learn how to get started with PhotoEditorSDK in Vanilla JavaScript. Then, upload your texture image and a sticker with the Sticker feature. As shown below, you can position a sticker on top of the original image with a point-and-click UI:
Check out this feature on the PhotoEditorSDK demo page.
Conclusion
Today we learned how to add an overlay image to a WebGL texture in JavaScript with the three.js
library. That made it easier to deal with WebGL and 3D graphics. In detail, by using one of the many plugins supporting the Three.js project, we were able to add a sticker to a texture with just a bunch of lines of code.
On the other hand, 3D graphics remains a complex topic, especially regarding OpenGL Shading Language. Three.js tries to hide this encumbrance as much as possible, but sometimes it is unavoidable. If you want to avoid using WebGL directly to achieve your goal, consider an all-in-one and easy-to-use solution – such as PhotoEditorSDK.
Thanks for reading! We hope that you found this article helpful. Feel free to reach out to us on Twitter with any questions, comments, or suggestions.
To stay in the loop with our latest articles and case studies, subscribe to our Newsletter.