LittleGarden
Case Study
Overview
Little Garden is an interactive 3D web experience developed as my capstone project. The goal was to combine 3D modeling, real-time animation, and web interaction into one poetic and immersive website. The entire experience is rendered using Three.js and assets created in Blender.
Objectives
Create a fully interactive 3D environment that works smoothly in browsers.
Implement real-time character animations triggered by user input.
Explore visual storytelling through atmosphere, motion, and sound.
Challenge myself to build both the visual and code-based foundation of a 3D narrative space.
Tools Used
Daz Studio – For creating the base human model before further customization.
Blender – For modeling the character, clothing, feathers, and environment assets.
Botaniq (Blender Plugin) – For generating and customizing natural plants and trees used in the environment.
Three.js – For real-time rendering, animation, interactivity, and shader effects.
HTML/CSS – For UI elements like the loading page, dialog box, and sound toggle.
JavaScript – For building interaction logic, animation triggers, and scene transitions.
GLSL (Shader Language) – For creating custom fragment shaders like the dynamic screen noise effect.
Process Breakdown
After finalizing my project concept, I moved into asset creation and development across several stages:
1. Character Modeling and Rigging
I started by creating a base character model using Daz Studio’s Genesis 8.1.
I imported the model into Blender for sculpting and modification to better match my artistic vision, then re-imported it back into Daz Studio to apply a full skeletal rig with face controls.
After rigging, I imported the character into Blender using the Daz to Blender plugin and converted the skeleton into an MHX rig, enabling cleaner IK/FK switching and animation control. I designed four distinct actions using Blender’s Nonlinear Animation (NLA) Editor, which allows Three.js to recognize and trigger specific animation clips by name.
2. Hair Creation
For the character’s hair, I used Blender’s Particle System.
I separated the hair into several sections, manually grooming each cluster to ensure neatness and flow, a process that required significant patience and detail management.
Although I added hair physics simulation in Blender, this dynamic system was not carried over into Three.js due to real-time performance constraints.
3. Environment Modeling
Initially, I created a flat ground plane, but quickly realized it looked too empty and distorted when viewed with Three.js’ orbital rotation.
I redesigned the ground as a small floating island.
To populate the environment, I used the Botaniq plugin in Blender for generating trees, flowers, and rocks, and applied a Decimate Modifier to optimize polygon count for real-time rendering.
I sourced 4K textures from Poly Haven to enhance the island’s surface detail.
4. Clothing Design
I originally planned to use Marvelous Designer for clothing creation.
However, due to performance limitations, I modeled a princess dress directly in Blender by duplicating the character’s base mesh and using weight transfer for rigging.
To make the dress behave more naturally, I applied Blender’s cloth simulation to the dress.
I also created a short T-pose action at the beginning of the animation timeline to allow the cloth to settle naturally before character movements began, minimizing potential deformation during later animations.
5. Scene Assembly in Three.js
After completing the models, I imported all assets and animations into a Three.js environment set up using Vite.
To enrich the scene, I added:
Feather Particle System:
I imported a feather model from Blender and instantiated 500 floating feathers in Three.js.
Each feather was given random values for falling speed, rotation, and sway to create an organic, snow-like drifting effect.Grass Instancing:
I used InstancedMesh to scatter 15,000 blades of grass across the island.
Each instance was randomly rotated, scaled, and positioned within a defined radius to balance visual density and performance.
Initially, the scene appeared overly green and flat.
To improve the visual quality, I applied a Bloom effect to enhance lighting and experimented with an HDRI background.
Later, I replaced HDRI with a custom gradient sky shader for better performance.
I also implemented a custom fragment shader to overlay a subtle animated noise texture, giving the scene a softer, cinematic feel.
6. Interaction Design
I developed an interactive dialog box with two selectable options, each tied to different character animations.
If no interaction occurs, the character remains in the default standing animation.
Additionally, clicking directly on the character triggers a spin-around animation.
7. UI and Audio Integration
Inspired by the Atoms website, I designed a dynamic title animation and a custom CSS button effect.
However, due to the scene’s complexity and size, playing CSS animations while loading assets caused noticeable stuttering.
To solve this, I implemented a simple loading page that fully loads all models, textures, and animations before transitioning to the main interface.
This ensured the title animation could play smoothly without performance issues.
Additionally, I integrated background music with a sound wave ripple animation for a richer immersive experience.
Challenges & Learnings
When I first imported all models and animations into Three.js, I noticed that the scene appeared overly green, flat, and visually less appealing—even worse than Blender’s default Eevee render.
To achieve a more Cycles-like rendering quality, I implemented a combination of techniques:
I added a Bloom effect to enhance lighting glow, introduced a high-quality HDRI for realistic environmental lighting, and developed a Noise effect using a custom fragment shader to overlay a subtle cinematic grain.
These combined improvements significantly elevated the overall visual richness and made the scene feel closer to offline rendering standards.
However, I later found that the HDRI file was too large, causing long loading times and performance issues.
To balance visual quality with real-time performance, I removed the HDRI and instead built a custom gradient sky shader directly in Three.js.
This preserved the atmospheric depth while keeping the experience lightweight and responsive.
Because I used FK bones for the character’s legs, I encountered unexpected deformations where the skirt did not move naturally with leg animations.
To solve this, I slightly enlarged the skirt to minimize clipping issues.
This highlighted the importance of proper rigging and cloth simulation setup, and I plan to continue refining these technical skills in future projects.
Through this project, I strengthened my ability to:
Balance performance and visual quality in real-time WebGL rendering.
Develop and apply fragment shaders for cinematic effects like Noise.
Debug and optimize cloth simulation and skinning workflows.
Design immersive interactive experiences without relying on traditional narratives.
Outcome
Delivered a complete and polished interactive 3D web experience accessible across devices.
Demonstrated the ability to integrate visual design, technical implementation, and user interaction into a cohesive real-time project.
Gained deeper practical knowledge in creative coding, 3D asset workflows, and real-time rendering optimization.
GET IN TOUCH!
Interested in working together? I’m always open to exciting projects or collaboration.
