stephen-hqxu / superterrainplus

SuperTerrain+: A real-time procedural 3D infinite terrain engine with geographical features and photorealistic rendering.
MIT License
12 stars 1 forks source link

Implementing Texture Utilities for Rule-based Biome-dependent Texture Splatting #29

Closed stephen-hqxu closed 3 years ago

stephen-hqxu commented 3 years ago

This is a relatively simple PR, which introduces a few new classes for rule based terrain texture splatting and it will be integrated into the engine later, as well as various improvements to the overall terrain engine.

With that aside, the following issues are also fixed in this upcoming major release:


STPTextureDatabase

Texture database is a simple (or complex) database-like data structure that holds texture and assign different splatting rules with texture. Texture are organised in the following manner:

In addition to a storage space for holding texture data in a structural manner, STPTextureSplatBuilder, a subclass of STPTextureDatabase, aims to store and manage all terrain splat rules.Different biomes to have different rule sets, each rule denotes an active region; when the testing result for a rule passes, the texture linked to that rule is considered to be active and thus should be used to rendered. Currently there are two different rule sets being implemented:

Finally, texture database comes with a nice utility STPDatabaseView which allows querying a large number of results set to be simpler, reducing the time to communicate with the database system.

STPTextureFactory

Texture factory aims to convert texture configurations and rule sets in the texture database into a format that can be recognised and processed by other parts of the system such as shaders. Due to the various limitations on GPU, we decide to lookup everything using dictionaries (a separete array with indices to the value we are looking for). Terrain splat rule needs to be first looked up using sample (e.g. biome ID), and retrieve all rules for this biome; for each active region an index to the texture array will be provided, and from the texture array client can query type of map needed; finally to locate the map data an index to the layer and element within the layer is also provided.

Later texture factory will be the entry point for generating a terrain splat map on GPU (possibly with JIT compilcation), which contains the indices to the texture and lookup the map indices from the texture array within the shader.

Checklist

Texture utilities

General

stephen-hqxu commented 3 years ago

Rule-based biome-dependent texture splatting

Sounds very complicated, but what is that exactly. It's basically a set of rules that we follow and check for truth values, if yes we enable the texture at that portion on the terrain. Works like a decision tree, we use conditions to check for the value, and enable texture for true branch.

Altitude-based splatting

Gradient-based splatting

It also comes with the problem of texture blending. Like what we have before when doing smooth biome transition, different region has distinct rules, and the boundary may cut out sharply and impact visual quality. The state-of-the-art approach to solve this is by defining different region on separate channels, use channel ID to represent the texture to be activated, so we can control the amount or weight this texture should contribute to the final color.

However assigning one texture to each channel with a large the number of texture is pretty expensive, espeicially within the context of a procedural multi-biome terrain generator. It boils down to the problem of performing interpolation and filtering to an integer texture, for which we have done it perfectly with biome interpolation in #22 using our hand-made single histogram filter. Yet even though the performance of that filter is fine for generation, the speed is still not ideal for real-time rendering.

Our current idea is to use only a single channel of integer-format texture and fill each pixel with texture ID as a key to lookup the texture in the shader. For filtering, it might be a good idea to just use a simple convolution kernel because with some testing we found that a small kernel yeilds a better result than a large one when comes to texture splatting.