精選文章

SmallBurger Asset Home

  SmallBurger

2026年8月12日 星期三

Why Are Traditional Terrains Performance Killers on Mobile? Z-Terrain (Zero Deform Ultimate Mobile Landscape) Development Insights and Solutions

For a long time, implementing expansive, open-world landscapes on mobile devices has been an extremely tricky task. Because running Unity's native Terrain system directly on mobile phones incurs completely unacceptable performance overhead, the industry's conventional compromise is to use plugins like Mesh Terrain Editor Free or Terrain To Mesh to convert the terrain into Meshes for rendering.

However, this long-standing conventional pipeline hides three "fatal pain points" that cause the most headaches for R&D teams:

Pain Point 1: Unnecessary Waste of Geometry in Flat Areas (Vertex Pressure)

When traditional plugins convert native terrain to a Mesh, they typically can only use a naive, uniform subdivision algorithm. This leads to a very absurd phenomenon: a perfectly flat beach or grassy plain is assigned the exact same density of triangles and vertices as a steep cliff.


These densely packed vertices, which offer zero visual contribution, needlessly waste the computational resources of the Vertex Shader on mobile GPUs, resulting in a severe geometric performance burden.

Pain Point 2: Water Bodies and River "Relocation Hell" (Extremely High Late-Stage Maintenance Costs)

The traditional Terrain-to-Mesh pipeline is a "destructive, irreversible" one-way process. In large-scale scene development, terrain rarely exists in isolation; it is often deeply integrated with water systems like lakes, rivers, and waterfalls.

When a Level Designer (LD) or Director casually says late in development: "We need to expand the village here, move this river 50 meters to the left, and make the lake a bit larger," the nightmare for artists officially begins: They have to 'level the previous holes and dig new ones,' and then re-export the Mesh.


Excavation and lining are required to construct a lake.

Pain Point 3: Transition Blending Between Cliffs (Scene Objects) and Terrain

Because traditional Terrain inherently suffers from vertical UV stretching issues, the system does not automatically add vertices (Vertices) on steep cliffs with extreme height differences to distribute the resolution, leading to severely distorted textures.

To solve this visual disaster, artists typically have to "place a large number of rocks, mountains, and other scene objects" in these areas to forcefully cover up the ugly parts. But this introduces a new problem: extremely stiff seams (complete disconnects in lighting and textures) appear at the intersection of the objects and the terrain. To hide this rigid seam, artists are forced to densely pack the surrounding area with grass and small pebbles. For project teams with extreme demands on visual quality and scene cleanliness, this approach is not only extremely tedious but also needlessly stacks a massive amount of Draw Calls and polygon counts.


There is a noticeable hard edge where the terrain meets the mountain.

Pain Point 4: Quantity Limits on Multi-Layer Texture Blending (Splat Mapping)

To express surface richness, traditional terrain needs to blend multiple Textures like grass, rocks, and sand. If conventional Texture2D is used directly for multi-layer blending, the Shader will declare failure right at the compilation stage due to hardware limits on Sampler registers and Texture Binding counts (for example, on conventional mid-to-low-end Android OpenGL ES 3.0/3.1 devices, the upper limit is only 16).

A common compromise solution in the industry is to use Multi-Pass (multi-channel rendering) to split up the layers. However, large terrains already have a very high vertex/polygon count; this approach not only doubles the geometric pressure but also causes severe Overdraw bandwidth overhead on mobile devices by forcing the terrain to be repeatedly drawn across the full screen, with lighting and shadows calculated multiple times.


When Unity's native terrain needs to blend more than 5 layers of textures (in this case, 2 control maps, along with 8 albedo and 8 normal maps), the underlying system is forced to switch to Multi-Pass rendering. Through the Frame Debugger, we can clearly see that the terrain is brutally rendered twice, resulting in a severe waste of performance.


Solving the Landscape Dilemma: Z-Terrain's Underlying Architecture and Core Philosophy

Having developed mobile games for a long time, I noticed that the terrains artists create are actually mostly flat ground, and ultimately, atmospheric richness is achieved by stacking a large number of scene objects. Furthermore, I have personally deeply felt the pain of late-stage artists having to repeatedly level and re-dig terrain when "moving lakes and changing rivers."

So I thought: Is it possible to completely solve the terrain by solely "placing scene objects"? Let the terrain itself have absolutely no Deform (geometric bumps or depressions). If I can just handle the "edge transition blending between objects and the ground" perfectly, and allow the ground to "reveal objects situated below the surface (like lake bottoms or underground rivers)," wouldn't that perfectly achieve the goal of a large open terrain while simultaneously liberating the artists' productivity?

Z-Terrain in-game rendering: The ground is a completely flat mesh with zero deformation (Zero Deform). All landforms (lakes, mountains, and even underground cracks and depressions) are pieced together from independent objects, and perfect edge transition blending and downward surface penetration are achieved through the underlying Shader. 

Letting the Data Speak: S8 Performance Benchmark (13-Layer TileMap Blending)

The concept sounds wonderful, but can the performance really hold up when actually deployed to the underlying hardware?

To test the limits of Z-Terrain, we deliberately chose an extremely outdated mobile device by today's standards—a Samsung Galaxy S8 (Mali-G71 GPU)—for a hellish stress test.

We crazily stacked 13 layers of detail texture blending on the Z-Terrain (including 13 Albedo and 13 Normal maps, totaling 26 texture assets and 28 samples), and used a brush to arbitrarily paint complex landscape details on the ground.

The actual test results completely shattered the performance ceiling of traditional terrain systems:


Even on the legacy S8 platform (Mali GPU), a 13-layer blend—including both Albedo and Normal maps—still manages to run at a locked 60 fps with stable performance.

Frame Debugger panel: The entire open-world ground rendering consumes only 1 Draw Call. The other Draw Call circled above is independently occupied by the lake object.


Once you exceed 5 layers on a native Unity Terrain—meaning you open a second Control map—you have to draw (render) the Terrain two or more times.

Revealing the Core Black Magic: How Did I Force a 13-Layer Blend on Mobile?

The main reason traditional terrains cannot use One-Pass rendering is that their TileMaps do not utilize TextureArray, causing the number of Texture Bindings to exceed hardware limits. So, simply replacing the single-texture architecture of the TerrainLayer with a TextureArray should do the trick.

But it's not that simple; multiple Control Maps suffer from the exact same hardware flaw. Therefore, Z-Terrain comprehensively consolidates both of these into TextureArrays, suppressing the number of Texture Bindings used to the absolute extreme:


It consolidates the 13 layers of ground surface details (Albedo/Smoothness) into a single Texture Array of 13 Slices, occupying only 1 texture slot.


Multiple Control Maps cannot escape the fate of being arrayed. Under a 13-layer surface blend, a single terrain chunk originally required 3 independent Control Maps (12 channels); Z-Terrain directly consolidates multiple Control Maps into a single TextureArray, fundamentally resolving the register and Texture Binding limits during multi-layer blending.

Breaking the Visual Bottleneck: Perfect Edge Transition Blending Between Objects and Ground

This is the utmost priority of the entire Z-Terrain system. Since we opted for a "Zero Deform all-object workflow," the transition quality at the contact surfaces between objects and the ground directly determines the success or failure of the entire large scene.

To achieve perfect visual effects, Z-Terrain adopts the following architecture at the base level:


Live Demo: When dragging the object or tweaking the sliders, the mountain base textures and normals blend together dynamically with an extremely smooth gradient.

Implementation Philosophy: Globalized Assets and Multi-Dimensional Transitions

The core to Z-Terrain achieving seamless transitions lies in the globalization of Control Map (weight map) and Tile Map (detail texture) data:

  • World Space Sampling: Whether it's the flat Quad ground serving as the foundation, or any scene objects placed on top of it (like mountains or rocks), they all uniformly use world coordinates (World Space Position.xz) within the Shader to sample textures and weights. This means objects and the ground share the exact same data perspective at the pixel level, naturally possessing continuity.
  • Height Blending Weights: Utilizing the Global weight data from the ground's control map, combined with the depth relationship of object pixels, it dynamically controls the transition range and blending weights of edge materials via blending sliders, achieving a visual deception effect identical to native Terrain Deform (terrain upheaval).
  • Dual Blending of Texture and Normal: If blending is only done on the Albedo texture, lighting will instantly reveal the trick because the normal directions of the object and the ground don't match. Z-Terrain achieves smooth transition of both textures and ground Normals simultaneously at the boundaries, ensuring that shadows and highlights remain completely continuous and unbroken when lit.

This is a fantastic solution for the notorious terrain UV stretching issue. It turns out that even when utilizing Unity's Terrain system, scattering environment assets remains unavoidable.

Another Key Point: Downward Surface Penetration (Reveal Processing)

For traditional terrain systems to create lakes, rivers, or cracks, the only pipeline is to use a heightmap to Deform (dig out a depression downwards) and then cover it with a Plane Mesh (water surface mesh) on top to simulate the water body.

The core goal of Z-Terrain is to completely abandon this high-maintenance deformation operation. We want to be able to simply place a lake object to quickly modify a level. But this brings a soul-searching challenge: on a completely flat ground mesh, how do you allow the line of sight to penetrate the ground and see objects hidden below the surface?


The lake depth fade and shoreline textures blend seamlessly.


The crack asset can also seamlessly intersect with flat surfaces and achieve a perfect edge blend.

Abandoning Stencil, Pivoting to an Extreme Blending Rendering Strategy

In the early stages of technical implementation, the most intuitive approach was to use the Stencil Buffer to carve out the ground. However, after actual stress testing, to ensure the perfect blending quality of semi-transparent transitions for ground materials, I ultimately abandoned the Stencil solution and adopted an extremely clever combination technique:

Alpha Blending + Cull Off + Back-face occluding forward surface.

Although this approach slightly sacrifices some Overdraw overhead on mobile TBDR architectures, the return is unparalleled: we successfully achieved a pixel-level, high-quality "downward surface penetration effect" that perfectly complies with correct perspective occlusion relationships on a completely flat Quad mesh. Artists no longer need to re-bake heightmaps; simply drop a lake object, and the underlying Shader automatically digs open the ground.

By disabling culling (Cull Off) and implementing occlusion logic, the system ensures that the terrain mesh is precisely hidden under any perspective view, revealing only the intended underlying content.

The Cross-Control Map Boundary Issue (Breadth Solution)

When facing an extremely massive terrain, the resolution of a single Control Map usually hits an upper limit. The conventional industry practice is to slice the terrain into many chunks (Pages). However, this triggers a catastrophic pipeline disaster during "object blending": when a massive mountain crosses a chunk boundary, the object Shader cannot dynamically decide which Control Map to sample.


Z-Terrain stress test: Even when the object is placed directly at the center of a four-page quad-intersection, the underlying system maintains absolutely precise, fluid, and seamless material blending.

Pixel-Level "Breadth" Slice Conversion Mechanism

Z-Terrain comprehensively processes Control Maps into TextureArrays. No matter how many Pages the map is divided into, to the GPU, they are simply different Slices within the same texture register. The Shader directly uses the pixel's world coordinates to perform breadth mathematical formula conversions, dynamically calculating exactly which terrain chunk grid the current pixel is stepping on. This ensures that it only ever needs to sample the corresponding chunk's Control Map exactly once.

The Soul of the Toolchain: Real-Time Editing with TextureArray

If the rendering performance is robust but causes the artist to experience severe lag during editing, the system is still a failure. To end this pipeline pain point, Z-Terrain utilizes a proprietary brush tool driven entirely by Compute Shaders:


Z-Terrain Brush Editing Interface
  1. Precise Pixel-Level Addressing: Compute Shaders possess extremely powerful parallel read/write capabilities (RWTexture2DArray). It precisely addresses and overwrites weights solely for the pixels covered by the current brush radius.
  2. Inherently Friendly Output Targets: Because CS can directly write data into specific Slices of a TextureArray, the brushing feel is incredibly silky smooth, completely solving the historical nightmare of "unbearable lag".
For more details on the Compute Shader brush, please refer to my previous article here:

Conclusion: The Ultimate Answer for Next-Gen Mobile Terrains

Z-Terrain wasn't born to reinvent the wheel, but to forge a bloody path for art pipelines and rendering bandwidth within the extreme constraints of mobile performance. We can intuitively see the decisive differences:

  • 1. Geometry Polygon Pressure: Unity Native Terrain (Extremely High) vs. Z-Terrain (Zero Pressure - flat quad mesh).
  • 2. Landform Modification Cost: Traditional Plugins (Destructive pipeline hell) vs. Z-Terrain (Extremely Low - all-object workflow, place and modify at will).
  • 3. Multi-Layer Material Blending: Unity Native Terrain (Forces Multi-Pass > 5 layers) vs. Z-Terrain (Powerfully supports 13+ layers in 1-Pass).
  • 4. Cross-Page Edge Transition: Traditional Plugins (Unsolvable) vs. Z-Terrain (Perfectly seamless via global world coordinates).
  • 5. Mobile Draw Call Overhead: Traditional Plugins (Increases linearly) vs. Z-Terrain (Extreme batching, constant 1-Draw Call via SRP Batcher).

Z-Terrain proves one thing: in mobile graphics development, the top-tier optimization isn't usually optimizing the old pipeline, but rather thoroughly subverting and reconstructing from the base data structures and art pipelines.

The reference youtube:


You can get it here:

Z-Terrain: Zero Deform Ultimate Mobile Landscape

Associated Asset Page:

https://assetstore.unity.com/publishers/86820

2026年3月3日 星期二

Development Insights: GPUDrivenForwardPlus



I have always been deeply fascinated by Forward Plus lighting architectures. Before the official URP Forward Plus was released, I implemented a custom Forward Plus solution for URP based on Depth Pre-pass, known as ForwardPlusURP

The core logic of that version followed the classic Tile-based Forward+ approach: it rendered a depth pre-pass to calculate the depth range for each tile and performed light culling to reduce the cost of light loops in the fragment shader.

2026年1月8日 星期四

SmallBurger Plugins Now Support Unity 6.3 LTS

 

A selection of SmallBurger Asset Store plugins has been tested and verified with Unity 6.3 LTS.


Currently, 8 out of 21 plugins have been validated on Unity 6.3 LTS.

Additional plugins will be tested and updated progressively based on project priorities.


You can find the complete SmallBurger plugin lineup on the Unity Asset Store publisher page:

👉 Smallburger

2025年12月17日 星期三

🌸GPU-Driven Poetic Dynamics: From Simulating Ghost of Tsushima’s Iconic Flower Field to the Birth of a Complete Vegetation System

 

In my previous post, Simulating Ghost of Tsushima’s Iconic White Flower Field in Unity, I wrote:

“I hope it can eventually run just as smoothly on mobile devices.”

That goal was achieved sooner than expected.
And that white flower field is no longer alone.

Today, the same architecture can support twenty types of vegetation — all processed on the GPU — handling wind simulation, interaction, painting, and culling simultaneously.

This article is not merely a showcase of results, but a record of the journey — from a simple flower field experiment to a complete vegetation system.
A journey to find what I call “poetic dynamics” on the GPU.

2025年11月25日 星期二

Camera-Adherent GPU Particles 1.0.3 — Multi-Light, Forward+, and Hybrid Lighting Upgrade


The 1.0.3 update brings a major visual improvement to the Camera-Adherent GPU Particle system.

This release focuses purely on foreground, camera-facing particle effects—such as wind swirls, impact bursts, weapon trails, magic glows, atmosphere streaks, UI-adjacent FX, and any particle that stays tightly aligned to the screen.

These particles now react to lighting in a way that matches the rest of your scene’s illumination—without losing the performance advantages of a camera-adherent GPU pipeline.

2025年10月13日 星期一

Simulating Ghost of Tsushima’s Iconic White Flower Field in Unity

 

I’ve always been fascinated by the vegetation system in Ghost of Tsushima.
After finishing the grass part earlier, I finally decided to tackle the iconic white flower field.

2025年9月30日 星期二

Building a Cross-Platform GPU Procedural Grass System in Unity URP (Optimized for Mobile)


Recently, I’ve been working on a project called UnityURP-Procedural-DrawMeshInstancedIndirect, and I’d like to share some advantages of procedural generation.

Unlike traditional methods that rely on massive Transform Buffers or GameObject instances, this approach dynamically generates grass using ComputeShaders. For culling, I use a RenderTexture to store results (since SSBOs aren’t supported in many mobile VertexShaders), ensuring compatibility with most mobile devices.

This architecture significantly improves load times and performance, especially on mid- to low-end phones. Let’s break down the key design concepts step by step.