2011-10-03 86 views
12

我试图使用WebGL创建3D地形。我有一个带地形纹理的jpg,另一个jpg的高度值(-1到1)。WebGL - 具有高度贴图的纹理地形

我看各个包装库(比如SpiderGL和three.js所),但我不能找到一个sutable例子,如果我这样做(如在three.js所)代码没有记录,我可以不知道该怎么做。

任何人都可以给我一个很好的教程或例子吗?

在Three.js http://mrdoob.github.com/three.js/examples/webgl_geometry_terrain.html有一个例子,这几乎是我想要的。问题在于他们随机创建了山脉的颜色和高度值。我想从2个不同的图像文件中读取这些值。

任何帮助将appriciated。 感谢

+0

只是一张纸条,JPEG可能不是一个地形的最佳格式,因为它是有损耗的,而JPEG文物最终会在你可能没有想到找地形微妙颠簸。 – izb

回答

5

两种方法,我能想到的:

  1. 为平面网格创建景观顶点。使用顶点纹理查找来查询你的高度图并调整每个点的高度(可能是你的Y分量)。这可能是最简单的,但我认为现在浏览器对它的支持不是很好。 (实际上,我找不到任何例子)
  2. 加载图像,将其渲染到画布,并使用它读回高度值。在此基础上构建一个静态网格。由于着色器的工作量较少,因此渲染速度可能会更快。但是,它需要更多代码才能构建网格。

对于读取图像数据的例子,你可以检查出this SO question.

+1

几乎在任何情况下,选项2对您都会更好。如果你正在渲染只是地形,因为所有的高程数据将被着色器单独知道,你会需要一些其他的方式来定位你的(大概)其他场景中的对象选项1只适用。 – Chiguireitor

12

退房这个职位在GitHub上:

https://github.com/mrdoob/three.js/issues/1003

通过florianf挂在那里的例子帮助我成为能够做到这一点。

function getHeightData(img) { 
    var canvas = document.createElement('canvas'); 
    canvas.width = 128; 
    canvas.height = 128; 
    var context = canvas.getContext('2d'); 

    var size = 128 * 128, data = new Float32Array(size); 

    context.drawImage(img,0,0); 

    for (var i = 0; i < size; i ++) { 
     data[i] = 0 
    } 

    var imgd = context.getImageData(0, 0, 128, 128); 
    var pix = imgd.data; 

    var j=0; 
    for (var i = 0, n = pix.length; i < n; i += (4)) { 
     var all = pix[i]+pix[i+1]+pix[i+2]; 
     data[j++] = all/30; 
    } 

    return data; 
} 

演示:http://oos.moxiecode.com/js_webgl/terrain/index.html

2

您可能感兴趣的话题我的博客文章:http://www.pheelicks.com/2014/03/rendering-large-terrains/

我着重就如何有效地创建地形几何形状,使得你的细节的适当水平在近场以及远处。

您可以查看此结果的演示:http://felixpalmer.github.io/lod-terrain/,所有的代码由在github:https://github.com/felixpalmer/lod-terrain

申请纹理地形,你需要做一个纹理查找在片段着色器,绘图空间中的位置到纹理中的位置。例如。

vec2 st = vPosition.xy/1024.0; 
vec3 color = texture2D(uColorTexture, st) 
0

根据您的GLSL的技能,你可以写一个GLSL顶点着色器,纹理分配给您的纹理通道之一,并阅读顶点着色器的值(我相信你需要一个现代化的卡读取纹理在顶点着色器中,但这可能只是我展现我的年龄:P)

在顶点着色器中,根据从纹理中读取的值来转换顶点的z值。

0

Babylon.js使这非常容易实现。您可以看到一个例子: Heightmap Playground

他们甚至已经用它实现的Cannon.js物理引擎,让您可以处理冲突:Heightmap with collisions

注:在写本书只用大炮工作.js物理插件,摩擦不起作用(必须设置为0)。此外,确保在设置物理状态之前设置网格/冒名顶替者的位置,否则会出现奇怪的行为。