求助:柏林噪声生成地形 模仿minecraft

isunLt 2017-05-18 11:14:45
本人大一计算机,学校课程要求我们做一个小项目,然后,我们组就想用three.js做一个网页版的MC。
看网上资料说minecraft地形是用柏林噪声算法实现的,我也尝试着用柏林噪声生成二维密度图
类似这种
但是事实上我生成的地图是这样凌乱的
我觉得我现在的这个密度图是上面的第5或第6种。可是我改持续度(persistence)、倍率(Octave)或者噪声生成函数(noise)里的那三个质数,也不能生成如第一张图中的第一种第二种那样的密度图。

我的思路是,用柏林噪声生成了密度图之后,在每个点上按照这个点上的值,在这个点上叠相应数量的土块。

下面是我的代码

var persistence1 = 0.001;
var Number_of_Octaves1 = 2;
function Noise(x,y){
var n=x+y*59;
n = (n >> 13) ^ n;
var nn = (n * (n * n * 15731 + 789211) + 700000001) & 0x7fffffff;
return 1.0 - (nn / 1073741824.0);
}
function SmoothedNoise(x,y) //光滑噪声
{
var corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
var sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8;
var center = Noise(x, y) / 4;
return corners + sides + center;
}
/**
* @return {number}
*/
function Cosine_Interpolate(a,b,x) // 余弦插值
{
var ft = x * 3.1415927;
var f = (1 - Math.cos(ft)) * 0.5;
return a*(1-f) + b*f;
}

/**
* @return {number}
*/
function InterpolatedNoise(x,y) // 获取插值噪声
{
var integer_X = parseInt(x);
var fractional_X = x - integer_X;
var integer_Y = parseInt(y);
var fractional_Y = y - integer_Y;
var v1 = SmoothedNoise(integer_X, integer_Y);
var v2 = SmoothedNoise(integer_X + 1, integer_Y);
var v3 = SmoothedNoise(integer_X, integer_Y + 1);
var v4 = SmoothedNoise(integer_X + 1, integer_Y + 1);
var i1 = Cosine_Interpolate(v1, v2, fractional_X);
var i2 = Cosine_Interpolate(v3, v4, fractional_X);
return Cosine_Interpolate(i1, i2, fractional_Y);
}

/**
* @return {number}
*/
function PerlinNoise(x,y) // 最终调用:根据(x,y)获得其对应的PerlinNoise值
{
var total = 0;
var p = persistence1;
var n = Number_of_Octaves1;
for(var i=0; i<n; i++)
{
var frequency = Math.pow(2,i);
var amplitude = Math.pow(p,i);
total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
}

return total;
}
//用createPlane()函数在每个点上按照这个点上的值,在这个点上叠相应数量的土块//
function createPlane() {

var l = worldSize / blockSize;
l=100;
console.log(l);

var planeSize=new Array(l);
for(var i=-l/2;i<l/2;i++)
{
planeSize[i]=new Array(l);
for(var j=-l/2;j<l/2;j++)
{
planeSize[i][j]=PerlinNoise(i,j);
for(var z=-1;z<planeSize[i][j]*20-1;z++)
scene.add(boxBuf(i,z,j));
}
}

for(var i = -l/2; i != l/2; ++i)

for(var j = -l/2; j != l/2; ++j) {

scene.add(boxBuf(i, -1, j));

}

}

我的问题是:
1、我的思路对不对。。。。(如果能生成一部分地图也可以,不用生成无限大地图)
2、如果是对的。怎么生成如图中第1、2种的密度图?
3、合成的时候,是用原始的noise函数值合成,然后再用插值函数插值,生成密度图还是怎么样?
4、网上说的种子(seed)是什么?


网上有一些大神的源代码,我看了很长时间,还是看不懂。太菜了。
请大神帮助。不胜感激!!!!
...全文
2287 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
RyuZhihao123 2017-05-26
  • 打赏
  • 举报
回复
引用 3楼我是你的主体 的回复:
哇,原来是这样,我是看了你的博客,没想到你会看到回复我的帖子哈哈哈哈。这个生成地形我搞了好久啦,还是搞不出来,后来我去学习了一下,你博客里引用的那个GitHub大神的代码,也不知道为什么就生成好了。现在才知道原来他simplex函数调用的时候,坐标乘上0.01是干什么。
现在我们的MC比以前好多了。

谢谢,非常感激!
很巧最近想玩玩论坛,不过这样渲染大量方块,效率应该是个问题,必要的裁剪,抑或采用树结构去分区管理地形会好的多(四叉,kd树,没必要用八叉树,因为虽然是三维,但是和二位高度图差不多,四叉树足以)
RyuZhihao123 2017-05-24
  • 打赏
  • 举报
回复
你好。我看到你贴的这段代码的注释,意识到你可能看的是我的博客[MyMinecraft]。之所以出现那个情况是噪声数据生成的间隔太大导致的。你的createPlane()函数中,是用i++取间隔的,整数的间隔有些过大。如果间隔为0.01这种小数会平滑狠多
isunLt 2017-05-24
  • 打赏
  • 举报
回复
哇,原来是这样,我是看了你的博客,没想到你会看到回复我的帖子哈哈哈哈。这个生成地形我搞了好久啦,还是搞不出来,后来我去学习了一下,你博客里引用的那个GitHub大神的代码,也不知道为什么就生成好了。现在才知道原来他simplex函数调用的时候,坐标乘上0.01是干什么。
现在我们的MC比以前好多了。

谢谢,非常感激!
业余草 2017-05-21
  • 打赏
  • 举报
回复
看标题都很复杂!


算了,还是搞不懂!

456

社区成员

发帖
与我相关
我的任务
社区描述
其它游戏引擎
社区管理员
  • 其它游戏引擎社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧