A 3D Watermelon Built with Three.js and Procedural Canvas Textures
Why is a watermelon worth rendering in 3D?
Because it's not just a red-and-green icon. The cut flesh, the thin white rind, the irregular dark and light stripes on the skin, the black seeds, and the water droplets fresh from the fridge — these are what make up everyone's shared memory of "the first bite of watermelon in summer."
This time I used npm + Three.js to build an interactive watermelon scene. When you open the page, the watermelon rotates slowly; you can drag with a mouse or finger to change the viewing angle; clicking "Cool Soundscape" even opens a subtle ambient sound. The focus isn't on piling up features, but on making it look more like a ripe, chilled watermelon.
Reusable Prompt (Professional Edition)
The prompt below can be used directly for similar creative frontend projects. It avoids merely describing "what to draw" and instead clarifies the delivery goal, technical boundaries, and acceptance criteria all at once.
Role: You are a creative frontend developer who balances visual quality with engineering implementation.
Task: Use npm, Vite, and Three.js to create a responsive 3D summer watermelon interactive page, using a visual language of "chilled, sweet, and juicy" to create a sense of coolness.
Delivery Requirements:
1. The first screen directly displays an interactive cut watermelon; do not create a marketing landing page.
2. Use real Three.js geometry, lighting, and materials to complete the scene; do not replace the main subject with static images.
3. The watermelon should include ripe, deep-red flesh, a thin white rind with a naturally transitioning edge, irregular dark and light skin stripes, black seeds, and condensation droplets.
4. Add restrained mint leaves, soft summer light, and Chinese text layout; the image should remain clean with ample negative space.
5. Support mouse and touch drag rotation; it should display correctly on both desktop and mobile.
6. Stripes must not repeat at equal intervals; the flesh must not appear pale or unripe; do not use fog effects that make distant objects look hazy.
Acceptance Criteria:
- At first glance, the image is identifiable as a ripe, chilled cut watermelon.
- Interaction does not obscure the main text; on mobile, text and model do not overlap.
- Running `npm run build` successfully generates a production build.
From "There's a Watermelon" to "It Looks Like a Watermelon"
After the first version was completed, the scene already had a half-cut melon, flesh, seeds, and interaction, but it wasn't realistic enough. The subsequent rounds of adjustments were actually the most valuable part of this production.
First, the distorted extra slice on the right side was removed. It was originally meant to enrich the image but actually disrupted the visual focus. Then the rind was redone: instead of using equidistant, identical geometric stripes, longitudinal growth stripes with varying widths, curves, and shades were generated on a Canvas and then applied as a texture to the hemispherical rind.
The flesh also went through several color adjustments. Too light and it looked unripe; too wide a white rind looked stiff; a hard edge between the red and white made it look like a plastic model. Ultimately, a radial gradient was used to connect the deep red flesh, light red transition, pale yellow-white rind, and green skin edge, and the red flesh area was expanded to cover most of the cut surface.
There's another easily overlooked detail: the early scene had fog enabled. It was meant to give the background more spatial depth, but actually made the distance look like it was covered with a white veil. After removing the fog, the watermelon's color, contrast, and silhouette all became much cleaner.
This reminded me that the most important thing in visual generation isn't "generation complete" in the first round, but continuous convergence based on real visual perception. User feedback like "looks unripe," "stripes are all the same," "looks foggy" are all specific enough to directly map to the three technical layers of material, texture, and lighting.
Key Implementation
The main subject of the scene is a flattened hemisphere: the bottom part uses sphere geometry to represent the rind, and the top surface uses a circular plane to represent the flesh. The black seeds are multiple scaled spheres, and the condensation droplets use a physical material with higher transparency and lower roughness.
The rind and flesh do not rely on external images. The code creates Canvases in the browser:
- The rind Canvas generates green stripes of different widths and bending directions;
- The flesh Canvas uses a radial gradient, smoothly transitioning from a deep red center to a thin white rind;
- Both Canvases are converted to
THREE.CanvasTextureand then mapped onto the corresponding meshes.
This approach has two advantages: first, no extra texture downloads are needed, making the page startup lighter; second, the texture's color, proportions, and randomness can all be adjusted directly through code. For a stylized 3D project like this, it's much easier to control than finding a temporary image.
The interaction part doesn't introduce extra controllers: it listens for pointer down and move events, mapping the displacement of the finger or mouse to the model's horizontal rotation and pitch angle. The model maintains a very slight auto-rotation when not being dragged, which makes the first screen "come alive" without stealing attention from the reading text.
Tech Stack Used This Time
| Name | Purpose |
|---|---|
| npm | Install and manage three, vite dependencies |
| Vite | Local development server and production build |
| Three.js | Responsible for camera, lighting, hemispherical rind, flesh, seeds, condensation, and render loop |
| CanvasTexture | Code-generated irregular rind texture and natural flesh gradient |
| Web Audio API | Opens subtle ambient sound via a button |
The core visuals of the watermelon page are entirely generated by Three.js geometry, lighting, and Canvas textures, without relying on static assets to replace the main subject. This preserves real-time rotation interaction and makes it easy to continuously adjust the flesh color, rind stripes, and water droplet texture.
Results and Review
This small piece ultimately has only one theme: when a user opens the webpage in summer, the first thing they see is a refreshingly cool watermelon.
It has no complex plot and doesn't need a heavy UI. Ripe red flesh, a natural rind, a few seeds, a bit of water droplets, paired with a 3D perspective you can rotate by hand, is enough to convey the feeling.
If you also want to use AI or Three.js to make a small web experience, my suggestion is don't just write "make me an XX." Add three things to your prompt: what the primary visual should be, how the user can interact, and which visual errors must be avoided. The first two determine whether the work is fun; the last one often determines whether the work looks like a finished product.
Top 1 from juejin.cn, machine-translated. The original thread is authoritative.
Is the watermelon guaranteed authentic? Watch out, Liu Huaqiang might come looking for trouble 😁😁😁