13

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

我查看了各种包装库(如 SpiderGL 和 Three.js),但我找不到一个合适的示例,如果我这样做(如 Three.js),则代码没有记录,我无法弄清楚怎么做。

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

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

任何帮助都将不胜感激。谢谢

4

5 回答 5

13

在 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

于 2012-05-09T11:13:18.990 回答
5

我能想到的两种方法:

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

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

于 2011-10-03T23:21:13.667 回答
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)
于 2014-05-28T16:27:40.510 回答
1

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

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

于 2014-07-22T17:58:34.837 回答
0

Babylon.js 使这非常容易实现。您可以在以下位置查看示例: Heightmap Playground

他们甚至用它实现了 Cannon.js 物理引擎,因此您可以处理碰撞:Heightmap with collisions

注意:在撰写本文时,它仅适用于 cannon.js 物理插件,并且摩擦不起作用(必须设置为 0)。此外,请确保在设置物理状态之前设置网格/冒名顶替者的位置,否则会出现奇怪的行为。

于 2017-01-13T20:54:49.763 回答