2016-01-06 48 views
2

簡而言之,我將生成的值的地形(二維高度圖)平滑回距離原始值。基於廣場內距離的收益遞減

有是,僅僅使用所生成的值的6部平坦區域,接着,從移動的3單元的平滑區中產生的回原始(使9個)

在平坦區域中的所有的x,z值被賦予例如4的y值,然後3個平滑單元應該移回零,意味着3,然後是2,然後是1,如果零是我們的原始數字,這將使下一步(等式外部)回到0 。

從試驗和錯誤,似乎我需要分別計算角落和邊緣,因爲角落的最大距離是對角線,或4.24,而邊緣的最大距離只是3.我試過一個數字囉嗦的方法來得到我所在的地方,但它仍然無法工作。不言而喻,儘管我仍然會說,但我不是數學魔法師。

任何人都可以把他們的大腦圍繞這個比我更好嗎?

Vector3 pos = holeCenter - terrain.transform.position; 

    //flatten area 
    int posX = Mathf.FloorToInt(pos.x * (td.heightmapResolution/td.size.x)); 
    int posZ = Mathf.FloorToInt(pos.z * (td.heightmapResolution/td.size.z)); 
    float[,] heightMap = td.GetHeights(0, 0, td.heightmapResolution, td.heightmapResolution); 
    float height = heightMap[posZ, posX]; 
    int modZone = 9; 
    int flatZone = 6; 
    for (int x = posX - modZone; x <= posX + modZone; x++) { 
     for (int z = posZ - modZone; z <= posZ + modZone; z++) { 
      //if within 6 of cave ent (flat zone) 
      if (x >= posX - flatZone && x <= posX + flatZone && z >= posZ - flatZone && z <= posZ + flatZone) { 
       heightMap[z, x] = height + Random.Range(-0.00015f, 0.00015f); 
      } 
      //otherwise apply gently to the three rings around the flat area 
      else { 
       //if on a corner 
       bool corner = false; 
       if (x < posX - flatZone) { 
        if (z > posZ + flatZone) { 
         corner = true; 
        } 
        else if (z < posZ - flatZone) { 
         corner = true; 
        } 
       } 
       else if (x > posX + flatZone) { 
        if (z > posZ + flatZone) { 
         corner = true; 
        } 
        else if (z < posZ - flatZone) { 
         corner = true; 
        } 
       } 

       if (corner) { 
        //apply the new height to the old height decreasingly based on distance 
        float dist = Mathf.Sqrt(Mathf.Pow(Mathf.Abs(posX - x) - flatZone, 2f) + 
         Mathf.Pow(Mathf.Abs(posZ - z) - flatZone, 2f)); 
        float maxDist = Mathf.Sqrt(Mathf.Pow(modZone - flatZone, 2f) * 2); 
        float multiplier = dist/maxDist; 
        heightMap[z, x] = (heightMap[z, x] * multiplier) + (height * (1 - multiplier)) + Random.Range(-0.00015f, 0.00015f); 
       } 
       else { //for an edge, only one value is in the modZone, find which, then apply 
        if (x < posX - flatZone || x > posX + flatZone) { 
         float multiplier = (Mathf.Abs(x - posX) - flatZone)/4f; 
         heightMap[x, z] = (heightMap[z, x] * multiplier) + (height * (1 - multiplier)) + Random.Range(-0.00015f, 0.00015f); 
        } 
        else { 
         float multiplier = (Mathf.Abs(z - posZ) - flatZone)/4f; 
         heightMap[x, z] = (heightMap[z, x] * multiplier) + (height * (1 - multiplier)) + Random.Range(-0.00015f, 0.00015f); 
        } 
       } 
      } 
     } 
    } 
    td.SetHeights(0, 0, heightMap); 

回答

0

我在回到它之後纔開始工作。

int modZone = 11; 
    int flatZone = 7; 
    for (int x = posX - modZone; x <= posX + modZone; x++) { 
     for (int z = posZ - modZone; z <= posZ + modZone; z++) { 
      float dist = Mathf.Sqrt(Mathf.Pow(Mathf.Abs(x - posX), 2f) + Mathf.Pow(Mathf.Abs(z - posZ), 2f)); 
      if (dist <= flatZone) { heightMap[z, x] = height + Random.Range(-0.00015f, 0.00015f); } 
      else { 
       float multiplier = Mathf.Clamp01((modZone - dist)/(modZone - flatZone)); 
       heightMap[z, x] = (heightMap[z, x] * (1 - multiplier)) + ((height + Random.Range(0, 0.0003f)) * multiplier); 
      } 
     } 
    } 

我放棄了方法,但它工作得很好,圓方法工作正常。可能會更好地適應更多變化的情況。