kulifmor.com

Creating Engaging 3D Particles in WebGL: Insights and Updates

Written on

Chapter 1: Introduction to 3D Particle Systems

Particle systems are captivating to observe. The sight of countless particles dispersing in various directions is not only enjoyable but also highly functional. Many visual effects in video games and animations, such as fire, smoke, dust, rain, snow, and spell effects, rely on particle systems. This week, I integrated 3D particle systems into my Sparrow WebGL engine.

3D Particles vs. 2D Particles

Several months ago, I introduced 2D particles that share many similarities with their 3D counterparts. The distinctions primarily lie in the addition of a third dimension affecting parameters like position, velocity, and acceleration, while attributes such as size, age, color, and texture remain consistent.

The most significant variation from 2D to 3D is that 3D particles must always orient towards the camera, a technique known as billboarding. I've previously discussed this in another devlog. Given my experience with implementing 3D particles in C++ and OpenGL, the transition to my WebGL engine was relatively straightforward.

In WebGL, geometry shaders aren't available, which differs from OpenGL. Instead, I utilized the same instanced rendering method used for 2D particles, where the geometry of the particle quad remains constant while only its position and age are updated each frame. This approach reduces the data sent to the GPU, requiring just a single vec4 (3 floats for position and 1 float for age). To allow for varied sizes and colors from a single emitter, I included an additional instanced buffer that holds per-particle size and color data.

Emitter Functionality

Emitters can be configured in three ways: as a point where all particles originate at a single location, or as a box or sphere from which particles spawn at random positions within the defined volume. The emitter’s settings dictate how the particles behave, which can be specified during the emitter's construction.

To simplify the particle management process, I streamlined the particle manager compared to my previous 2D implementation and C++/OpenGL version. In those versions, a particle manager or controller needed to be created before adding emitters. While this allowed for multiple controllers, I found it unnecessary at this stage. Now, a single particle manager is automatically created within the engine, enabling instant addition of emitters. The engine also takes care of updating and rendering, relieving the user of these responsibilities.

Visualization of 3D particles in WebGL

Depth Sorting Challenges

When rendering semi-transparent objects in 3D, it’s essential to render triangles from back to front to accurately blend colors. This presents challenges for particles due to their random positions and movements. Sorting them by distance from the camera can be computationally intensive, especially with thousands of particles. Some effective heuristics include sorting emitters by depth or rendering based on particle age, but I haven't incorporated these techniques yet.

Surprisingly, you can achieve decent results without semi-transparent particles, especially in non-realistic styles. Textures can be created with fully transparent pixels, as the fragment shader will discard fragments with an alpha value below 0.5. For instance, the simple fire texture I used only contains fully transparent or fully opaque pixels, similar to how particles are handled in games like Minecraft.

Chapter 2: UI Enhancements and Emitter Control

The most labor-intensive aspect of adding particles was developing their options menu. After implementing the particle system, I realized the need for a more efficient method to adjust particle settings in real-time. Initially, changing parameters required refreshing the page to view updates, which was not ideal for creating diverse particle effects. Thus, I decided to design an in-engine menu for real-time adjustments and concurrently redesigned the UI elements.

I began with a fresh spin box design, inspired by Blender, featuring < and > buttons to modify values. However, placing these buttons adjacent to the text input created visual issues. Instead, I introduced a new advancedBorderWidth feature, allowing for customizable border widths on each side.

In addition to the spin boxes, I developed new drop-down menus and toggle buttons. The toggle button was simple to create, resembling an oversized checkbox with text. The drop-down menu required more effort, as it included a popup that appears upon clicking.

To enhance texture generation for UI elements, I consolidated the overlapping functionalities into a new class, facilitating the creation of consistent textures across various UI components.

With all these UI improvements and the numerous tweaks to the particle options menu, the implementation took several days, but I am pleased with the outcome. However, this means I will need to redesign other engine menus to match this new style.

Comparison of old and new particle UI designs

Emitter Management and Future Plans

Beyond the emitter options menu, I also developed a feature that displays a list of all emitters. Users can create, rename, and delete emitters, marking the first instance in the engine where such control is possible. This foreshadows a future where users can create and manage various elements within the engine. Currently, the engine state is not persistent, necessitating users to copy options back to the JavaScript source code after creating an emitter.

I am quite satisfied with how the 3D particle system has evolved, particularly with the in-engine creation and editing workflow. The options menu simplifies adjustments and provides immediate visual feedback. While there are countless improvements to consider, the system is robust enough for the time being.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Avoid the Trap: 3 Reasons Not to Compare Yourself to Your Ex

Discover why comparing yourself to an ex can undermine your happiness and self-worth.

Unlocking Unique Python Development Opportunities in the Gig Economy

Explore unconventional ways for Python developers to monetize their skills and thrive in the gig economy, from IoT solutions to educational content.

Top Machine Learning Blogs You Should Follow in 2024

Discover the top machine learning blogs to stay updated on research and trends in 2024.

The Four Inactions That Sabotage Your Brain Health

Discover four detrimental inactions that can age your brain faster, as explained by neuroscientist Dr. Wendy Suzuki.

Unlocking Your Potential: 5 Effective Strategies to Finish Projects

Discover five impactful strategies to help you complete your projects and overcome procrastination.

How to Select the Ideal Cryptocurrency for Mining in 2024

Discover how to choose the best cryptocurrency for mining in 2024, focusing on profitability, algorithms, and market trends.

Essential WebExtensions for Everyday Browsing

Discover my top 5 WebExtensions that enhance productivity and streamline your online experience.

Achieving $100K as a Freelancer: My Journey to Success

Discover how I transitioned from small projects to landing a $100K freelance client through strategic networking and skill-building.