国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

如何在unity中手寫一個(gè)四叉樹地形lod系統(tǒng)(二)

這篇具有很好參考價(jià)值的文章主要介紹了如何在unity中手寫一個(gè)四叉樹地形lod系統(tǒng)(二)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

  在根據(jù)四叉樹節(jié)點(diǎn)創(chuàng)建了1365個(gè)地形分塊網(wǎng)格并保存到本地后,我們接下來要在游戲運(yùn)行的過程中動(dòng)態(tài)地顯示所需的網(wǎng)格,這是最關(guān)鍵的一步。

  如何根據(jù)攝像機(jī)位置動(dòng)態(tài)地選擇地形塊?這其中體現(xiàn)了由整體到局部,從簡(jiǎn)單到復(fù)雜的原則。

  0、 我們首先創(chuàng)建三個(gè)緩存列表。

  1、 我們先將索引為0的地形分塊(即最高LOD等級(jí))的分塊放入BufferA;

  2、 然后遍歷BufferA,判斷BufferA中的每一個(gè)元素是否符合“無需更加詳細(xì)”的條件,如果是,將它放入BufferFinal,否則放入BufferB;

  3、 在遍歷完BufferA中的元素后,清空BufferA,將BufferB的元素全部復(fù)制到BufferA中,清空BufferB;

  4、 重復(fù)2-3步驟的操作,直到BufferA、BufferB列表均空。

  此時(shí)BufferFinal中存儲(chǔ)的索引即是我們最終所需要的地形網(wǎng)格分塊的索引。

  我們把以上的操作封裝成函數(shù),在游戲開始運(yùn)行時(shí)調(diào)用一次。這一部分的代碼如下:

  

    private void TerrainGen()   // 生成(更新)地形網(wǎng)格
    {
        // 使用了子物體網(wǎng)格的方法,而不是網(wǎng)格合并的方法

        // 因此需要首先清除所有子物體
        for (int i = 0; i < transform.childCount; i++)
        {
            Destroy(transform.GetChild(i).gameObject);
        }


        // 四叉樹計(jì)算
        // 三個(gè)buffer計(jì)算方法
        List<int> BufferA = new List<int>();
        List<int> BufferB = new List<int>();
        List<int> FinalBuffer = new List<int>();

        Vector3 ppos = player.transform.position;

        // 迭代計(jì)算
        BufferA.Add(0);             // bufferA初始化,加入根節(jié)點(diǎn)
        while (BufferA.Count != 0)  // 當(dāng)bufferA不為空時(shí)
        {
            while (BufferA.Count != 0)   // 遍歷buffera每個(gè)值
            { 
                int i = BufferA[0];
                float dist = Mathf.Sqrt(Mathf.Pow((qTree[i].begin_Pos.x + 64 * qTree[i].interval) * 5 - ppos.z, 2) + Mathf.Pow((qTree[i].begin_Pos.y + 64 * qTree[i].interval) * 5 - ppos.x, 2));   // 計(jì)算瓦片中心距離玩家位置的水平距離
                
                BufferA.Remove(i);

                if (dist >= 0.8 * 128 * qTree[i].interval * 5)   // 1表示1倍瓦片邊長(zhǎng);128表示瓦片行列數(shù);5時(shí)xzbias(此處其實(shí)應(yīng)該參數(shù)化)
                {
                    // 那么這張瓦片距離玩家太遠(yuǎn),可以直接使用當(dāng)前l(fā)od,不用細(xì)化
                    FinalBuffer.Add(i);
                }
                else
                {
                    // 否則這張瓦片距離玩家很近,如果有更小的lod,應(yīng)該細(xì)化;
                    if(qTree[i].LodLeval == 0)  // 如果已經(jīng)是最細(xì)節(jié)的瓦片了,那沒辦法了,直接顯示
                    {
                        FinalBuffer.Add(i);
                    }
                    else        // 否則把它的四個(gè)更細(xì)節(jié)的子節(jié)點(diǎn)加入到待計(jì)算的b buffer
                    {
                        for(int j = 1; j <= 4; j++)
                        {
                            BufferB.Add(i * 4 + j);
                        }
                    }
                }
            }

            // 將ab buffer交換
            foreach(int i in BufferB)
            {
                BufferA.Add(i);
            }
            BufferB.Clear();
        }


        Mesh[] tiles = new Mesh[FinalBuffer.Count];

        Material mat = GetComponent<Renderer>().material;

        for (int i = 0; i < FinalBuffer.Count; i++)
        {
            tiles[i] = new Mesh();
            tiles[i].indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            string path = @"Assets\LodMeshes\LodMesh_" + FinalBuffer[i].ToString() + ".asset";
            tiles[i] = (Mesh)AssetDatabase.LoadAssetAtPath(path, typeof(Mesh));

            GameObject theTile = new GameObject();
            theTile.transform.parent = this.transform;
            theTile.name = "lod_" + i.ToString();
            theTile.AddComponent<MeshFilter>();
            theTile.AddComponent<MeshRenderer>();
            theTile.AddComponent<Renderer>();

            theTile.GetComponent<MeshFilter>().mesh = new Mesh();
            theTile.GetComponent<MeshFilter>().mesh = tiles[i];
            theTile.GetComponent<Renderer>().material = mat;
        }


    }

?

?????? 這一部分我選擇將需要的網(wǎng)格實(shí)例化到子對(duì)象中而沒有合并,如果需要優(yōu)化的話,應(yīng)該將網(wǎng)格合并成一個(gè),可以減少DrawCall的數(shù)量。

?????? 同時(shí)要注意的是:網(wǎng)格的實(shí)例化與顯示并非在每一幀進(jìn)行,可以維護(hù)一個(gè)數(shù)對(duì)來表示玩家攝像機(jī)所在的區(qū)域,如果玩家攝像機(jī)離開了原本的區(qū)域進(jìn)入到新的區(qū)域中,那我們便執(zhí)行一此地形網(wǎng)格更新操作:

    void Update()
    {
        if((int)player.transform.position.x / (64 * 5) != x_area || (int)player.transform.position.z / (64 * 5) != z_area)  // 玩家區(qū)域改變
        {
            TerrainGen();
            x_area = (int)player.transform.position.x / (64 * 5);
            z_area = (int)player.transform.position.z / (64 * 5);
        }
    }

  補(bǔ)充一點(diǎn),在此之前我們可以從本地讀取,在上一節(jié)生成網(wǎng)格時(shí)保存的四叉樹信息,這部分代碼很簡(jiǎn)單,如下所示:

    private void ReadQTree()
    {
        using(StreamReader RawTerrainData = new StreamReader(@"E:\Unity\MyProjects\Desert_01\Assets\TerrainTree\MyQTree.txt"))
        {
            string line;
            for (int i = 0; i < qTree.Length; i++)   // 讀取所有頂點(diǎn)   并且給原始uv數(shù)據(jù)賦值
            {
                line = RawTerrainData.ReadLine();
                string[] stringdata = line.Split(' ');

                // 讀取并寫入
                float.TryParse(stringdata[0], out qTree[i].begin_Pos.x);
                float.TryParse(stringdata[1], out qTree[i].begin_Pos.y);
                int.TryParse(stringdata[2], out qTree[i].interval);
                int.TryParse(stringdata[3], out qTree[i].LodLeval);
                float.TryParse(stringdata[4], out qTree[i].Center.x);
                float.TryParse(stringdata[5], out qTree[i].Center.y);

            }
        }
    }

  最終的效果如下:

如何在unity中手寫一個(gè)四叉樹地形lod系統(tǒng)(二)

如何在unity中手寫一個(gè)四叉樹地形lod系統(tǒng)(二)

  至此,我們大致完成了一個(gè)非?;A(chǔ)的一個(gè)四叉樹網(wǎng)格地形系統(tǒng),這其中還有很多問題,我大致思考了一下改進(jìn)的方向:

  性能優(yōu)化方面的問題問題,比如顯示的網(wǎng)格應(yīng)該合并成一個(gè)而非保持多個(gè)對(duì)象;明顯超出視線范圍的地形網(wǎng)格分塊應(yīng)該直接剔除掉而非繼續(xù)顯示等;

?????? 代碼復(fù)用性的方面的問題,有許多數(shù)據(jù)直接寫死在代碼里面,導(dǎo)致耦合度過高。在改進(jìn)的時(shí)候,應(yīng)該將這些數(shù)據(jù)參數(shù)化,將算法更優(yōu)化,來降低耦合度,增強(qiáng)代碼對(duì)不同大小的地形的復(fù)用能力;

?????? 效果實(shí)現(xiàn)方面的問題,沒有考慮不同LOD等級(jí)的地塊的連接處的露縫問題,應(yīng)該在后續(xù)中改進(jìn)

?????? 這里我僅僅實(shí)現(xiàn)了最基本的網(wǎng)格動(dòng)態(tài)顯示,沒有考慮渲染,在以后的改進(jìn)中,我會(huì)嘗試在地形渲染方面做出更多改進(jìn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-482221.html

到了這里,關(guān)于如何在unity中手寫一個(gè)四叉樹地形lod系統(tǒng)(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Unity制作一個(gè)地形,下載地形資源、繪制地形,添加樹、草,草可擺動(dòng)

    Unity制作一個(gè)地形,下載地形資源、繪制地形,添加樹、草,草可擺動(dòng)

    選擇了Terrain Tools,添加至我的資源 在unity中打開 菜單欄 ?窗口 包管理器,找到已經(jīng)獲取的資源 下載并導(dǎo)入 全選、導(dǎo)入 ?方法二: 導(dǎo)入已經(jīng)下載過的資源 (.unitypackage:Unity package file) 資源菜單 - 導(dǎo)入/項(xiàng)目視圖 - 資源 - 右鍵 - 導(dǎo)入/直接拖拽進(jìn)項(xiàng)目視圖 - 資源 打開下載的資

    2024年01月22日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)——四叉樹

    數(shù)據(jù)結(jié)構(gòu)——四叉樹

    四叉樹(Quadtree)是一種用于表示和管理二維空間的樹狀數(shù)據(jù)結(jié)構(gòu)。它將二維空間遞歸地分割成四個(gè)象限,每個(gè)象限可以繼續(xù)分割,以實(shí)現(xiàn)對(duì)空間的更精細(xì)的劃分。四叉樹通常用于解決空間搜索和查詢問題,例如碰撞檢測(cè)、圖像壓縮、地理信息系統(tǒng)等領(lǐng)域。 特別適合大規(guī)模的

    2024年02月07日
    瀏覽(15)
  • unity如何繪制地形

    unity如何繪制地形?Unity的地形是由一個(gè)特殊的組件稱為Terrain來創(chuàng)建的。這個(gè)組件可以讓你在Unity中創(chuàng)建非常復(fù)雜的地形,包括山脈、山谷、河流、湖泊等等。 在Unity中創(chuàng)建地形非常簡(jiǎn)單,只需要在場(chǎng)景中創(chuàng)建一個(gè)空對(duì)象,然后在Inspector面板中點(diǎn)擊“Add Component”,選擇“Terr

    2024年02月09日
    瀏覽(18)
  • 四叉樹圖像模糊(C代碼及實(shí)現(xiàn)思路)

    四叉樹圖像模糊(C代碼及實(shí)現(xiàn)思路)

    原創(chuàng)文章,參考文章見末尾,僅供學(xué)習(xí)交流使用,如果對(duì)你有幫助,請(qǐng)一鍵三連~ 代碼如有需要會(huì)整理上傳~ 能夠正確的對(duì)圖像建立四叉樹; 對(duì)于輸入的圖像,四叉樹能夠輸出模糊的結(jié)果 對(duì)顏色相近的區(qū)域進(jìn)行模糊 背景知識(shí)理解 PPM文件格式理解 PPM 是通過RGB三種顏色顯現(xiàn)的圖

    2024年02月02日
    瀏覽(21)
  • Unity地形系統(tǒng)Terrain

    Unity地形系統(tǒng)Terrain

    1.Terrain組件介紹 2.Raise or Lower Terrain介紹 ????????按shift+鼠標(biāo)左鍵,將抹平降低地形。 3.Set Height簡(jiǎn)單介紹 ? ? ? ? Height設(shè)置可升高地形的最大高度。 ????????通過Flatten all可整體抬高地形,結(jié)合?Raise or Lower Terrain降低地形,可以制作出洼地。再添加河流特效調(diào)整至洼地

    2024年02月08日
    瀏覽(21)
  • 空間數(shù)據(jù)結(jié)構(gòu)(四叉樹、八叉樹、BVH樹、BSP樹、k-d樹)

    空間數(shù)據(jù)結(jié)構(gòu)(四叉樹、八叉樹、BVH樹、BSP樹、k-d樹)

    在游戲程序中,利用空間數(shù)據(jù)結(jié)構(gòu)加速計(jì)算往往是非常重要的優(yōu)化思想,空間數(shù)據(jù)結(jié)構(gòu)可以應(yīng)用于場(chǎng)景管理、渲染、物理、游戲邏輯等方面。 2.1 四叉樹 四叉樹是很常見的一種 2D 碰撞檢測(cè)方法,實(shí)現(xiàn)手段也五花八門。不過在具體實(shí)現(xiàn)中要注意優(yōu)化細(xì)節(jié),控制建樹時(shí)間消耗與建

    2024年01月19日
    瀏覽(16)
  • 數(shù)據(jù)結(jié)構(gòu)與算法大作業(yè)——四叉樹自適應(yīng)模糊

    數(shù)據(jù)結(jié)構(gòu)與算法大作業(yè)——四叉樹自適應(yīng)模糊

    能夠正確的對(duì)圖像建立四叉樹; 對(duì)于輸入的圖像,四叉樹能夠輸出模糊的結(jié)果 對(duì)顏色相近的區(qū)域進(jìn)行模糊 可通過十六進(jìn)制編輯器 010editor 打開查看二進(jìn)制信息 官網(wǎng)獲取 010editor 信息 含義 P6 指明PPM的編碼格式 2156 2156 圖像大小為2156*2156 255 RGB的每個(gè)色彩值范圍為0~255 C0 91 89(

    2024年01月19日
    瀏覽(22)
  • 【Unity地編】地形系統(tǒng)搭建入門詳解

    【Unity地編】地形系統(tǒng)搭建入門詳解

    ?????個(gè)人主頁(yè) :@元宇宙-秩沅 ????? hallo 歡迎 點(diǎn)贊?? 收藏? 留言?? 加關(guān)注?! ????? 本文由 秩沅 原創(chuàng) ????? 收錄于專欄 : UI_Unity專欄 ??? GameObject 3D Object Terrain 1.創(chuàng)建鄰近地形 直接點(diǎn)擊相鄰方塊即可創(chuàng)建 2.筆刷 筆刷參數(shù)詳解 Raise or Lower Terrain:提升或降低高

    2024年02月08日
    瀏覽(30)
  • C#幾何算法:空間索引——Quadtree四叉樹及應(yīng)用(一)

    C#幾何算法:空間索引——Quadtree四叉樹及應(yīng)用(一)

    目錄 前言 什么是四叉樹? 四叉樹的原理 結(jié)語 ????????最近在CAD中開發(fā)拓?fù)錂z查和空間分析功能時(shí)發(fā)現(xiàn),傳統(tǒng)的雙層遞歸法會(huì)極大的降低程序運(yùn)行速度,就比如:圖上有1000個(gè)圖形,我們要求圖形之間的交點(diǎn),傳統(tǒng)的作法就是遍歷兩次圖形,在兩次循環(huán)中分別對(duì)圖形求交處

    2024年02月06日
    瀏覽(26)
  • Unity如何給地形進(jìn)行“縮放處理”(改變尺寸)

    Unity如何給地形進(jìn)行“縮放處理”(改變尺寸)

    入門小菜鳥,希望像做筆記記錄自己學(xué)的東西,也希望能幫助到同樣入門的人,更希望大佬們幫忙糾錯(cuò)啦~侵權(quán)立刪。 ??首先,我們先導(dǎo)入地形 點(diǎn)擊“游戲?qū)ο蟆薄?D對(duì)象”——“地形” ??縮放誤區(qū) 本來呢,在一般情況下是可以通過調(diào)節(jié)這個(gè)來實(shí)現(xiàn)對(duì)物體的縮放 但是地

    2024年02月11日
    瀏覽(36)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包