{"id":662,"date":"2011-10-31T16:22:46","date_gmt":"2011-10-31T12:52:46","guid":{"rendered":"http:\/\/www.blog.seganx.com\/?p=662"},"modified":"2024-03-18T17:32:57","modified_gmt":"2024-03-18T17:32:57","slug":"terrain-geometry","status":"publish","type":"post","link":"https:\/\/sajad-b.com\/?p=662","title":{"rendered":"Terrain :: Geometry"},"content":{"rendered":"<p>The Terrain for SeganX engine is going to be completed. in this post, I will describe the geometry algorithms I used for rendering the terrain briefly. my approach to designing this feature was easy to use, simple, and straightforward to implement. Artist\/Level designer can easily:<br \/>\n&#8211; create geometry everywhere and every amount that was required.<br \/>\n&#8211; increase performance by implementing LOD and patching geometries to reach minimum draw call.<\/p>\n<p>As I mentioned before, everything in the scene is a kind of node member (Component). In this method, the terrain is like the other members ( mesh, particle, sound, \u2026 ). The terrain is a node member too. Thus for importing terrain to the scene, we must create terrain attach it to the node, and then add the node to the scene. so we can create any number of terrain and add them to the scene. But to reach the goals mentioned above I designed terrain members with some more information.<\/p>\n<p><strong>Geometry data<\/strong><br \/>\nEach terrain member has a fixed 33\u00d733 vertices placed in grid style. I chose this size because I want to generate 6 levels of detail. With 33\u00d733 vertices we have 32\u00d732 quads for the first level. This means if we half each level 6 times, finally we will have one quad for the lowest level of details. Choosing vertices for each level will be done by using 6 static fixed-size LOD structures called <strong>TerrainLOD<\/strong> that are used for all Terrain members. Thus, there is no need for more indices\/vertices for each level and we just choose a correct LOD structure depending on view distance. So for rendering all terrain members, I used a big buffer and appended to that big buffer vertices of all terrain members in the view port. The appending process is just applied on vertices which are described in the LOD structure. Finally, the terrain will be drawn by one draw call.<\/p>\n<p><strong>T-junction problem<\/strong><br \/>\nT-junction problem appears between terrain blocks with different LODs and makes terrain ugly. The picture below illustrates this problem clearly:<\/p>\n<div id=\"attachment_671\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/T-Junction.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-671\" class=\"size-medium wp-image-671\" title=\"T-Junction\" src=\"https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/T-Junction.jpg?resize=300%2C225&#038;ssl=1\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/T-Junction.jpg?resize=300%2C225&amp;ssl=1 300w, https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/T-Junction.jpg?w=400&amp;ssl=1 400w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-671\" class=\"wp-caption-text\">T-Junction between LODs<\/p><\/div>\n<p>There are several ways to remove these junction problems. according to the &#8216;Geometry Data&#8217; of terrain in the engine I defined and implemented a simple structure to describe indices for each LOD. this structure splits indices for each LOD into 9 parts:<\/p>\n<div class=\"codecolorer-container cpp railscasts\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"cpp codecolorer\"><span class=\"kw4\">typedef<\/span> <span class=\"kw4\">struct<\/span> TerrainLOD<br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; TerrainChunk&nbsp; &nbsp; center<span class=\"sy4\">;<\/span> &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ &nbsp;standard center<\/span><br \/>\n&nbsp; &nbsp; TerrainChunk&nbsp; &nbsp; sideFUL<span class=\"br0\">&#91;<\/span><span class=\"nu0\">4<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy4\">;<\/span> &nbsp; &nbsp; <span class=\"co1\">\/\/ &nbsp;standard 4 sides<\/span><br \/>\n&nbsp; &nbsp; TerrainChunk&nbsp; &nbsp; sideLOD<span class=\"br0\">&#91;<\/span><span class=\"nu0\">4<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy4\">;<\/span> &nbsp; &nbsp; <span class=\"co1\">\/\/ &nbsp;simplified 4 sides<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"sy2\">*<\/span>PTerrainLOD<span class=\"sy4\">;<\/span><\/div><\/div>\n<p>Indices of <strong>center<\/strong> in this structure contain polygon indices that cover the center except for 4 sides &#8220;up, right, down, left&#8221;. these sides will covered by <strong>sideFUL<\/strong> or <strong>sideLOD<\/strong>. <strong>sideFUL<\/strong> contains indices to cover all polygons in that LOD and <strong>sideLOD<\/strong> contain simplified indices.<\/p>\n<p>Choosing which side ( <strong>sideFUL<\/strong> or <strong>sideLOD<\/strong> ) to use as indices is simple. we can easily predict the LOD of neighbors. to predict the LOD of each neighbor I compute the neighbor&#8217;s position by adding fixed terrain size to the current position. By putting this position to some special functions we can get the neighbor&#8217;s LOD number depending on current camera properties. for each neighbor that uses fewer details, we append <strong>sideLOD<\/strong> to the big buffer, otherwise, we use <strong>sideFUL<\/strong>. here is a screenshot for terrain in wireframe mode :<\/p>\n<div id=\"attachment_674\" style=\"width: 810px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/seganx-Terrain.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-674\" class=\"wp-image-674 size-full\" title=\"seganx Terrain\" src=\"https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/seganx-Terrain.jpg?resize=625%2C469&#038;ssl=1\" alt=\"\" width=\"625\" height=\"469\" srcset=\"https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/seganx-Terrain.jpg?w=800&amp;ssl=1 800w, https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/seganx-Terrain.jpg?resize=300%2C225&amp;ssl=1 300w, https:\/\/i0.wp.com\/sajad-b.com\/wp-content\/uploads\/2011\/10\/seganx-Terrain.jpg?resize=768%2C576&amp;ssl=1 768w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><p id=\"caption-attachment-674\" class=\"wp-caption-text\">Terrain rendering in SeganX engine<\/p><\/div>\n<p>My next task is choosing and implementing a terrain material system. The current system supports multilayer material systems. but implementing brush, and gathering information about each brush on terrain to increase performance, optimization and optimization and optimization still need more and more and more work. but now I have to spend more time on to Rush for Glory game project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Terrain for SeganX engine is going to be completed. in this post, I will describe the geometry algorithms I used for rendering the terrain briefly. my approach to designing this feature was easy to use, simple, and straightforward to implement. Artist\/Level designer can easily: &#8211; create geometry everywhere and every amount that was required. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[7],"tags":[34,36,51,53],"class_list":["post-662","post","type-post","status-publish","format-standard","hentry","category-engine","tag-patch","tag-rendering","tag-t-junction","tag-terrain"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/sajad-b.com\/index.php?rest_route=\/wp\/v2\/posts\/662","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sajad-b.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sajad-b.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sajad-b.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sajad-b.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=662"}],"version-history":[{"count":2,"href":"https:\/\/sajad-b.com\/index.php?rest_route=\/wp\/v2\/posts\/662\/revisions"}],"predecessor-version":[{"id":875,"href":"https:\/\/sajad-b.com\/index.php?rest_route=\/wp\/v2\/posts\/662\/revisions\/875"}],"wp:attachment":[{"href":"https:\/\/sajad-b.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sajad-b.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=662"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sajad-b.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}