代码本色0章——Perlin噪声生成起伏地形

代码本色0章——Perlin噪声生成起伏地形

此博文依据代码本色第0章中的随机数与Perlin噪声运用写成,并观看了丹尼尔希夫曼关于perlin噪声的讲解,https://www.youtube.com/watch?v=D8UgRyRnvXU,大家可以看一看

参考案例

在这里插入图片描述在这里插入图片描述

效果图

在这里插入图片描述

Perlin噪声

一个好的随机数生成器能产生互不关联且毫无规律的随机数。跟我们前面看到的一样,一定程度的随机性有利于有机体和生命活动的建模。然而,单独把随机性作为唯一指导原则是不够的,它并不完全符合自然界的特征,Perlin噪声将这一点考虑在内了,此算法可用于生成各种自然特效,包括云层、地形和大理石纹理。
Perlin噪声算法表现出了一定的自然性,因为它能生成符合自然排序(“平滑”)的伪随机数序列。
processing内置了Perlin噪声算法的实现:noise()函数。noise()函数可以有1~3个参数,分别代表,一维,二维,三维的随机数。

在这里插入图片描述图(a)
在这里插入图片描述图(b)
图(a)为noise函数,图(b)为random函数可见noise函数更为光滑,没有图(b)中小球跳跃的感觉,可见,noise函数可以是的图形更加平滑和连续。

void setup()
 {   
  size(400, 400); 
 }
float t=3;   
void draw()
   {   
    background(255); 
    translate(100,100);    
    float n=map(noise(t),0,1,-100,100);   
    ellipse(n,180,16,16);  
    t+=0.1; 
   } 

此代码看起来很简单,但是切记需要用,map()函数来约束noise的范围,关于map函数可以在官网reference找到,这里就不解释了。

地形绘制

首先观察上面的图,会发现一下规律:
1.起伏的地形由很多三角形组成,且三角形大小相同;
2.地形起伏随机;
从图上我们只能看出这么多信息。下面我们来实践

三角形区域创建
在这里插入图片描述
//

首先,第一步,我们先生成多个小网格,首先就会想到用rect()函数,于是生成了上面,但是我们发现,如果是这样,生成三角形就会有困难,因为效果图中绘制的三角形并不在直线上,因此我们想到processing自带的vertex()函数,于是图形又成了这样
在这里插入图片描述

//

int cols,rows;
  int density=20; 
   void setup() 
   {    
   size(600, 400);    
   int w=600;    
   int h=800;    
   cols=w/density;    
   rows=h/density;
     }  
  void draw() 
 {    
  background(0);   
  stroke(255);    
  noFill();    
  for(int x=0;x<cols;x++)    
  {      
  beginShape(TRIANGLE_STRIP);     
  for(int y=0;y<rows-1;y++)      
  {        
  vertex(y*density,x*density);        
  vertex(y*density,(x+1)*density);      
  }      
  endShape();    
  }  
} 

//

完成上面的步骤之后,我们会发现这还只是在二维平面上的,我们要怎么样转成三维的呢?其实只要在size()里面加入P3D这个参数即可,所以图形又变成了这样。
在这里插入图片描述
///
这个地方要注意的是,成为三维图形之后,需要调整角度,即用rotate()函数将图形转一转,同时还需要调整图形显示的地方才可以看见,不然就是一条线或者一片黑。同时随时改变三角形的顶点,即可生成如下效果。
在这里插入图片描述
/

//
为了使用方便我们新建一个二维矩阵,存储变化的点。
代码如下:

  float[][] terrain;  
  void setup() {    
  size(600, 600,P3D);    
  cols=w/density;    
  rows=h/density;     
  terrain=new float[cols][rows];  
  }    
  void draw() 
  {      
  for(int x=0;x<cols;x++)    
  {      
  for(int y=0;y<rows;y++)        
  terrain[x][y]=map(noise(x,y),0,1,-50,50);    
  }    
  background(0);    
  stroke(255);    
  noFill();    
  translate(width/2,height/2);    
  rotateX(PI/4);    
  translate(-w/2,-h/2);    
  for(int x=0;x<cols;x++)    
  {      
  beginShape(TRIANGLE_STRIP);      
  for(int y=0;y<rows-1;y++)     
   {       
    vertex(y*density,x*density,terrain[x][y]);        
    vertex(y*density,(x+1)*density,terrain[x][y+1]);      
    }      
    endShape();    
    }  
}  

之后呢,我们需要让此地形起伏慢一点并且,能够运动起来,我们选择其中的因此,可知我们只需改变noise()的x,y值即可,以y为例,我们每次绘制的时候都变化0.1(加减都可);

jump-=0.1;    
float yoff=0;    
for(int y=0;y<rows;y++)    
{      
float xoff=jump;      
for(int x=0;x<cols;x++)      
{        
terrain[x][y]=map(noise(xoff,yoff),0,1,-100,100);        
xoff+=0.2;      
}      
yoff+=0.2;    
} 

上面的代码段加载draw函数中,这样才能动起来
在这里插入图片描述
至此,我们就完成了地形构造。改变其中的density可以改变地形的平缓度,改变下off,yoff,可以让地形沿着不同的方向生成,大家感兴趣可以自己试一试!
为了方便大家,以下贴出所有代码。

int cols,rows;  
int density =20;  
int w=2000;  
int h=1600;  
float[][] terrain;  
float jump=0;  
void setup()  
{    
size(600,600,P3D);    
cols=w/density;    
rows=h/density;    
terrain=new float[cols][rows];  
}  
void draw()  
{         
jump-=0.1;    
float yoff=jump;    
for(int y=0;y<rows;y++)    
{      
float xoff=0;      
for(int x=0;x<cols;x++)      
{        
terrain[x][y]=map(noise(xoff,yoff),0,1,-100,100);        
xoff+=0.2;      
}      
yoff+=0.2;    
}     
background(0);     
stroke(255);     
noFill();        
translate(width/2,height/2+50);     
rotateX(PI/3);     
translate(-w/2,-h/2);    
for(int y=0;y<rows-1;y++)    
{      
beginShape(TRIANGLE_STRIP);            
for(int x=0;x<cols;x++)      
{        
vertex(x*density,y*density,terrain[x][y]);        
vertex(x*density,(y+1)*density,terrain[x][y+1]);      
}      
endShape();    
}        
 } 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我无法提供具体的柏林噪声生成地形的lua脚本代码,因为这通常涉及到复杂的数学算法和游戏开发中的纹理生成技术。然而,我可以为你概述柏林噪声生成的基本概念,并给出一个简单的伪代码示例。 **柏林噪声**是一种基于分形的伪随机噪声生成方法,常用于创建自然景观或纹理。在Lua中,实现柏林噪声可能会使用递归算法和一些数学运算。 **伪代码示例**(简化版): ```lua -- 定义两个随机数生成函数 (假设它们返回0到1之间的浮点数) local random = math.random local fade = function(t) return t * t * (3 - 2 * t) end -- 定义柏林噪声函数 function berkeleyNoise(x, y) local base = 64 local cellSize = 1 / base local octaves = 4 -- 多重振荡次数 local sum = 0 for i = 1, octaves do local frequency = base / pow(2, i) local amplitude = pow(0.5, i) local offsetX = x * frequency local offsetY = y * frequency sum += amplitude * noise(offsetX, offsetY) * fade(i / octaves) end return sum end -- 假设noise是一个内置函数,如Perlin Noise或Simplex Noise -- 这里只是简单展示,实际实现可能需要引入额外库或自定义函数 -- 使用噪声生成纹理或地形 local terrainHeight = berkeleyNoise(x, y) -- 可以根据生成的高度值调整地形表面 -- ... ``` 请注意,这个代码只是一个简化版本,实际实现会更复杂,并且可能需要利用现成的噪声库。如果你对如何在特定游戏引擎或工具中实现柏林噪声有兴趣,建议查阅相应文档或在线教程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值