Thursday, 6 August 2015

River Editing with Flood Placement

In the past I have found it difficult to create accurate looking rivers.  Partially this is because I was using semi circle segments for curves with no editable control points, so recently I have implemented rivers by using Bezier Curves. 

Still, it can be difficult to place control points at decreasing elevations, to ensure that the river flows down and that it does not rise above the ground.  I implemented a plane which effectively shows what terrain is down hill from the previous point and if the current control point is above the previous point. 

Adding this simple feature makes placing rivers much easier as the Flood Grid shows you the only possible regions which additional control points can be placed.

video


This video shows the interface for placing rivers with Flood Placement enabled.  The grid moves with the selector (3d cursor) and appears orange if the elevation of the current position is higher than the previous point in the river.  The end of this video shows the map loaded into a separate program which loads the features of the saved file.


Advanced Forest Generation with Map Editor

Over the past 5 years I have worked intermittently on a custom map editor for potential use in designing scenes for animations and environments for video games.

This past year I have done some major work refactoring the code for this editor and adding control forms for each layer to give a wide range of options and processes for creation.


The forest Layer of this editor now contains components to select forest textures from a library by forest regions (such as Boreal Forest, Dry Rocky Mountains, Coast Mountains)  Each texture set contains various textures containing different tree mixes at various densities.  With this control it allows for more accurate representational forest creation of various regions.


The Forest Editor also contains controls for procedural generation based on terrain elevation and slope aspect.  (These are generally the main factors determining forest types)


There are still controls for specific texture assignments, forest growth value modification and texture  randomization to allow for detailed editing of forests for the scene. 


Bellow is a video demonstrating most of the forest editing controls I have implemented.  First is using the detailed texture controls for editing terrain and forest textures, as well as the texture selector.  Second this video shows procedural forest generation and its functionality by modifying various parameters. 
video





Thursday, 13 November 2014

Refined General Displacement with Forest Rendering




With not too much work I was able to split the Data Buffers needed for general displacement and forest rendering, and then merge them to create an buffer that is input to generate the Displacement Key (the most expensive part of this process)  Again, the key of combining these processes before running the displacement filter is that the combination is relatively in expensive, and potentially many meshes using displacement can all use the same Displacement Key, which would not increase its computation time.

Bellow is a preview of terrain with displacement, and a vegetation layer on top of that displacement.

Left: Forest Rendering with Terrain Displacement
Right: Terrain with Height Map Displacement

This Combination of Terrain Displacement and Forest Rendering does not produce any additional artifacts than what is already inherent in the system and does not significantly increase running time.

Now it is kind of weird to have trees potentially growing straight out of rocks, but again, the forest layer could also be adapted to represent simply moss or grass, which would be fine.  Though regardless, trees often do grow straight out of rock piles and cliff faces, as seen bellow. 



For large boulder formations, a pass of the terrain could be rendered to the forest Modification Map, to over ride any trees in a specified area.



As mentioned above, the process for terrain displacement can also be extended to other meshes, such as ocean waves (to be explored soon...) as well as any thing else anchored to the ground with vertical texture.

Bellow is an experiment in implementing height map displacement with a rail road line. 


I am able to render this mesh with a special texture with the displacement height embedded into the alpha channel directly after rendering the terrain to the General Displacement Data Buffer.

Furthermore, it is easy to distinguish between having the vegetation grow on top of the terrain but not additional meshes in the layer (the depth value of the terrain and forest data will be same, other wise it is another mesh)




Above the displacement effect on the rails can be seen more easily.  Though there are some pretty ugly artifacts with this addition.   For one, the displaced terrain is cut vertically by the rail, which potentially could be smoothed out.  Second, the top of the rail is not flat, which again, rendering non organic (straight line) objects with this displacement system does not work well, due to using a mip map texture which smooths out straight surfaces.  Also there are some ugly artifacts along the edges of the track some times, but this may be due to the fact that the rail is flying in some places (a bad implementation)  potentially these could be smoothed out as well.

Though overal, the displacement of the rail line adds a lot of usable detail to the ties and the gravel on the rail bed, which could easily be combined with a separate mesh that renders the rails in 3D.


Above you can also see the Merged Displacement Data Buffer and the resulting Displacement Key.

Wednesday, 12 November 2014

Forest Rendering with Terrain Texture Displacement


Last summer I was working on a paper to essentialize the height-map displacement process I am using for the Forest Rendering Project.  Bellow is a break down for the basic rendering process to generate multi-textured terrain displacement that can accurately be merged with both opaque and transparent objects and effects.

 This work led me to realize that I could generate Displacement Data Buffers needed for terrain displacement as well as forest rendering, and merge them to share a single displacement key.

This means that in a single scene once some Height Map Displacement Filtering process is initialized, adding other systems to use this process of displacement could be added with relatively low processing cost to generate the needed data buffers, and then the creation of the displacement key (the process that calculates the displacement value) would not increase at all based on the addition of other systems also using the key.

Again, this is the advantage of this system, in that once implemented, the most costly process (generating the displacement key) does not increase with added complexity of the input data buffers 
as it operates as a 2D filter, and its running time is consistent.

Bellow is a sample of these processes being combined:



 This implementation is by no means perfect-the process relies on using shared data buffers for both forest generation and terrain displacement.  Using shared buffers allows for faster creation of the shared displacement key, but right now where forest exists it overrides any terrain displacement.  This is fine unless there are small holes in the forest (as in the bottom right of the image above) or if the rocks in the terrain texture are higher than the forest.



Currently both the forest and terrain displacement data buffers are generated sequentially on the same target, so they can not sample one another for a smooth merge.  Potentially the forest data could be rendered semi transparent to achieve smooth height transitions and simulating a layer of vegetation over the terrain.  Though as of now I am using all 4 channels of the main data buffer, so simply rendering the forest data over the terrain displacement data would probably destroy the final data embedded in the alpha channel.  Also by using this method there would be little control in how this merging is handled.


Alternatively the displacement data buffers could be split, then merged to handle smooth transitions and desired effects by having the forest become a dynamic vegetation overgrowth layer above the displaced terrain.  This will be explored and tested in the next post.

Forest Rendering Project resumes

It has been a while since posting to this blog, mainly because I have not been in a place to do any programming work for the past 6 months. Though as always, I have been thinking about improving this project to be more flexible and more able to represent various environments.



One observation is how essential geologic formations are to the character of different environments.

Rock Formations in Hylite Canyon near Bozeman, Montana


Previously I have adapted the forest system to handle rocks as a tree type, which is fine for static models but it became very tricky to have smooth transitions between forest and rock, and for differences in the static nature of rocks and the dynamic nature of vegetation... These environments would be both more flexible and realistic to separate vegetation, such as forests and terrain, such as rock formations.


Another observation is that this Forest Rendering System could be easily adapted to generate farm crops and grassy fields. 

Farm on the Gaspe Peninsula, Quebec

Rendering agricultural land is essential for almost every environment.  The groves and trenches in fields from irrigation systems and tractors could be embedded within one of the texture maps in a vegetation set, and then features such as roads and landings could be added similarly to forests using a modification map.






Another observation and thought about improving environmental rendering via height map displacement is possibility of using displacement to render 3D ocean waves.  Though subtle, this system could easily handle dynamic ripples and waves in the water as they could be rendered separately to a height map, which would be used to displace geometry representing the ocean.

Southern Gulf Island Coast, British Colombia

Using displacement for rendering ocean waves would be a subtle effect, but would potentially allow for fast rendering of an interactive ocean system that could be used in video games or simulations..



Finally, by either embedding structure objects in these environments or rendering buildings with vegetation textures, one could render complex and dynamic urban environments filled with grass, bushes and trees. 


Quebec City, Quebec


I have thought a lot about rendering towers and structures with vegetation on roofs, balconies and on walls.  Such 'green' buildings are inevitably becoming more popular in reality, and could also make for some interesting video game environments or anything depicting a more integrated and balanced future.

The above examples of rendering agriculture, complicated terrain, ocean waves and urban vegetation using both the Forest Rendering System and general Height map Displacement Filtering will be covered in the following posts.  I feel that by adapting this system to handle these features I will be able to render representative environments of most places on the planet, as well as a wide range of what the future may look like. 

Moving forward I am developing a system to support animation and video game environments.


Friday, 21 March 2014

Procedural Forest Generation with STRM height data

For animations to model development projects in the real world, I have worked on integrating a multi-textured forest system with a map editor which takes a height map as input for the terrain height values.


First I use the SRTM elevation database to generate a height map image of an area.  This image is easy to match up with other maps as overlays, which can be used to find features and as references for a map editor.






A method was added to my generic map editor, which automatically determines forest type depending on elevation.

This method is based off of the relative height values of the input height map, which blends texture weights for elevations.  This basic implementation ranges from rock out crops (above timber line) to thin forest, to dense forest, and mixed deciduous and pine at lower elevations.


After loading this map into a scene program, complete with depth effects, map elements etc, it is easy to see the overall effect of a dynamically created forest based on terrain features.  Though in this preview it is still easy to see grid lines of the forest textures.  This can be minimalized by randomizing forest values, such as randomizing thin forest values. 




Finally, I have an animation system so I can record values for different layers in real time, (such as camera motion, icon opacity etc.) to make refined compositions to show various interactions with the forest system.

Wednesday, 8 January 2014

Displacement Algorithm Implementation

This process of height map displacement may be advantageous in that running time is primarily independent on the complexity of the filtering algorithm used to calculate displacement.  Unlike other displacement algorithms, in which the displacement value must be calculated for every sample, the complexity of height map composition in this case does not significantly effect run time.

That being said, there are a few options to implement the displacement filter:

GPU shader
If implemented on the GPU, the displacement algorithm is basically a for loop checking up to Max_Displacement pixels bellow, and returning the index of the first valid location.  Though as register space is limited, this algorithm must be broken into several steps.

This method seems to work the best, but scales directly with the maximum displacement value.  Although this value can be scaled to simulate more displacement, but displacement is then culled closer to the screen.  The running time for this algorithm is dependent on the Max_Displacement value,




CPU processing
The displacement algorithm may also be implemented on the CPU, where variables may be stored and referenced cumulatively for each column in the image.  This advantage, being able to use global variables, allows for a significant speed up in running time, theoretically.

Each column in the image can be processed in a for loop, that keeps track of the current reference pixel and offset distance.  In this method, a while loop advanced the position of the reference pixel and calculates a new displacement value.  The while loop advances until a valid displacement value is found, or until the current and refrence pixel indices are equal, in which no displacement occurs for the current pixel.  This means that the cumulative executions of the while loops for each column will not exceed the image_height, thus running at O(HEIGHT * WIDTH).  Though most significantly, the running time for this algorithm is not dependent on the Max_Displacement value.

Though of course as this method is on the CPU, it is sequential, and requires time to transfer resources from the GPU, meaning it does not run in real time. (about 1-2 fps

GPU Direct Programming
As the above algorithm operates independently for each column, it is easily parallelized using direct programming with the GPU.  Although with the above implementation, parallelization is limited, as the execution paths for each unit are highly variable.  Additionally, transfering resources and switching rendering modes for the GPU is slow, which accounts for about 75% of the running time.  This algorithm currently runs at about 5-7 fps, although I definitely think it could be implemented in a more parallelized way.


These explanations here are quite simple and brief, but were are a significant portion of my research in developing this process.  I elaborate on the specifics of implementation in the paper I have been working on...