Good day.
We are working on a game with a procedurally generated landscape. It is defined by a function providing the height of every point in the XZ-plane. Furthermore, this function is supposed to deliver a strength for every defined ground material, making it possible to mix any count of materials at a certain point. The landscape will be displayed using a simple height map. Mathematically speaking, we’d just sum up the resulting material colors of all materials at a specific point, each multiplied by their respective strength at this point. The strengths could just be bilinearly interpolated within the cells of the height map. We expect that usual world functions will assign something like at most four ground materials to a single point. We’d still like to keep the mentioned general definition, because then we can also mix more materials if required and make transitions between different materials across the landscape as wide as we want them to be.
Now while I know pretty well, how I would achieve this with an own engine (e.g. based on OpenGL), I’m insecure of how to to it in Unreal and if it is even possible
. Maybe you guys can help, comment on my ideas, or provide own ones.![]()
Here is two approaches I have in mind so far:
- Rendering a single patch for every material in ADD mode. For every ground material, all triangles of the full height map are determined, where at least one corner has this material at least a bit. These patches will be distinct in great areas of the landscape but may also partly overlap using the same triangles. All these patches are rendered after each other, each using only the respective ground material and some GPU buffer defining the strengths of this material at every point used by a triangle. The render mode will be ADD, such that the colors of all passes will be added over each other. This will lead to a problem for objects that are behind the landscape (e.g. the skybox) or when the landscape covers itself at certain pixels, because pixels behind closer landscape pixels will still contribute to the final color. This would make the landscape kind of transparent in the end. My solution for this would be: As a first pass, render the full height map into the depth buffer and only the depth buffer (not in color!). Then render the material patches with ADD mode and depth test on EQUAL. That way only the pixels at the very front will make the final color, but if several material patches use the same triangles, their contributions may still add up at the points of the triangle. All other objects (including the skybox) can be rendered afterwards in normal REPLACE mode and with depth test LESS OR EQUAL.
My research so far yielded that this approach will only be possible by meddling with the Unreal engine code because e.g. the need for a specific render order arises. Is this correct? - Rendering the whole height map at once. Each triangle refers to a list of “components”. Each component is bound to a specific ground material. A triangle has one component for each ground material present in any of the three corners. Each component in addition to the material stores the strength for every corner. The fragment shader determines the triangle it is shading a pixel for, loops all components and sums up the material colors.
I expect this approach to be slower than the first, because the different shader invocations will iterate through the loop for different counts, which as far as I know is bad practice on the GPU, because cores with less invocations will be done earlier and remain idle until the others complete, wasting computing power. I still think, this approach will be performant enough because usually there will be at most four materials at a certain point making the total computation effort not too high… Speaking of doing this in Unreal without tempering with the engine code I see more potential. Still, I am not sure how advanced the usage of custom GPU buffers and accessing them in shaders is in Unreal (I’d need a reference from each triangle into another buffer storing the lists of components for each triangle. There, each component would consist of the material ID and three floats for the strengths of this material at the corners). Furthermore, I’d need a loop in the fragment shader with a count of invocations which will only be known at runtime. I don’t know if this is possible in Unreal and I’m not even sure if this is possible in general e.g. in OpenGL.
Sorry, for so much text, people!
I hope there will be someone who hasn’t fallen asleep after reading all of this and can share his/her thoughts. ![]()