带有高度图的纹理地形



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

我看过各种包装库(如SpiderGL和Three.js),但我找不到合适的例子,如果我这样做(如在Three.js)代码没有记录,我不知道如何做到这一点。

谁能给我一个好的教程或例子?

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

任何帮助将不胜感激。由于

在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

我能想到两个方法:

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

有关读取图像数据的示例,您可以查看这个SO问题

您可能对我关于这个主题的博客文章感兴趣: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)

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

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

巴比伦.js使这非常容易实现。你可以在下面看到一个例子:Heightmap操场

他们甚至用它实现了Cannon.js物理引擎,所以你可以处理碰撞:

注意:在写这篇文章时,它只适用于cannon.js物理插件,摩擦不起作用(必须设置为0)。此外,确保在设置物理状态之前设置网格/冒充者的位置,否则你会得到奇怪的行为。

最新更新