
This project showcases the website created for the design department of KAI Corporation, a Japanese company with 117 years of craftsmanship rooted in blade-making. The site reflects the refined aesthetic sensibility the brand has cultivated over its long history.
Rather than simply manufacturing products, KAI also considers the movements of the people who use its tools. From this idea came the main copy: “Cutting sharpness draws our lives.” The visuals and interactions were carefully shaped around this concept. The lines surrounding the products act as guidelines of motion—symbolizing how human gestures draw and shape daily life. Through interactive video scrubbing, visitors can experience the tactile sensation of using these tools. The site presents KAI’s aesthetic as a “touchable video” experience.
Two Technical Challenges
There were two major technical hurdles during development:
- Expressing naturally blurred lines with depth of field (DoF)
- Implementing video scrubbing that responds smoothly to drag interactions
The following sections explain how each challenge was approached.
Natural DoF for the Lines
Typical depth-of-field implementations on the web often leave a sharp core beneath stacked blur layers, creating an unnatural result. For example, here’s an image generated by Gemini that illustrates this common issue:

Unlike the DoF techniques used in traditional 3DCG software—which rely on a depth map—achieving a clean, natural blur purely in WebGL proved challenging. As a result, I explored a different approach (though I’d love to hear if anyone knows a better one):
- Render crisp, unblurred lines into an FBO.
- Render a second FBO that enlarges the lines by the blur radius and encodes additional data in its RGB channels:
- G = blur area
- R = blur intensity
- Combine the two and apply a planar Gaussian blur using a vertical and horizontal two-pass process.
To handle line intersections, the process is performed twice—once for the foreground and once for the background—separated by the origin.

Video Scrubbing
On modern Mac/Chrome environments, scrubbing can be implemented as simply as:
video.currentTime = sec;However, for cross-browser compatibility, two additional steps were required. First, each video was carefully re-encoded using ffmpeg. Not every parameter is essential, but the most important factor is shortening the keyframe interval. While -g 1 (All-Intra) turns every frame into an I-frame, the resulting file size wasn’t practical, so I opted for half that value instead.
ffmpeg \
-i INPUT.mov \
-hide_banner \
-c:v libx264 \
-crf 24 \
-y \
-pix_fmt yuv420p \
-an -sn -dn \ # Remove audio, subtitle, and data tracks
-map 0:v:0 \ # Keep only the main video track
-profile:v baseline \ # Lightweight decoding profile
-level 3.1 \ # Mobile compatibility
-g 12 -keyint_min 12 -sc_threshold 0 \ # Shorter keyframe interval for smoother scrubbing
-bf 0 -refs 1 \
-tune fastdecode \ # Reduce decoding cost
-x264-params "no-deblock=1:weightp=0:mbtree=0:rc-lookahead=0:aq-mode=0:subme=1:trellis=0:me=dia:partitions=none" \ # Disable heavy decoding features
-video_track_timescale 24000 \ # Fix tbn to 24000 for 24fps consistency
-movflags +faststart \ # Web-optimized header
OUTPUT.mp4Even so, Firefox compatibility remained an issue, so I added a WebCodecs-based fallback. I initially considered using mp4box, but ultimately chose mediabunny because it’s actively maintained and easier to work with.
import { ALL_FORMATS, BlobSource, Input, VideoSampleSink } from 'mediabunny';
...
const blobForDecode = await loadVideo(name, suffix);
this._input = new Input({
source: new BlobSource(blobForDecode),
formats: ALL_FORMATS,
});
const vtrack = await this._input.getPrimaryVideoTrack();
this._sink = new VideoSampleSink(vtrack);
this._canvas = document.createElement('canvas');
this._ctx = this._canvas.getContext('2d');
this._canvasTexture = new CanvasTexture(this._canvas);
this._canvas.width = vtrack.displayWidth;
this._canvas.height = vtrack.displayHeight;
...
this._sink.getSample(sec).then((sample) => {
const vFrame = sample.toVideoFrame();
this._ctx.drawImage(vFrame, 0, 0, this._canvas.width, this._canvas.height);
vFrame.close();
sample.close();
this._canvasTexture.needsUpdate = true;
});Line Animation Synced with Video
To animate the lines in 3D and keep them synchronized with the video, Blender was used. On the same timeline as the reference footage, the following elements were built in Blender, and a lightweight JSON was exported via Python:
- Line trajectories
- Timing of appearance and disappearance (controlled by moving cubes along the lines)
About mount inc.
We at mount inc. plan and produce a wide range of creative work, mainly websites—from campaign and promotional sites that communicate a product’s appeal to corporate information sites and online stores for fashion brands. We also work across film, print, and other media. Throughout every project, we strive to make no compromises. We face each challenge sincerely and aim to create something we can proudly show to anyone—something we ourselves truly love. With that spirit at our core, we continue to create work that brings meaningful value to both our clients and the world.
Visit our company website to see more of our projects.
#KAI #Design #Dept #Experience #WebGL #Line #Blur #Video #Scrubbing #Animation #Codrops