WebGL - 带有高度图的纹理地形

发布于 2024-12-07 23:46:32 字数 453 浏览 1 评论 0原文

我正在尝试使用 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 个不同的图像文件中读取这些值。

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

I'm trying to create a 3D terrain using WebGL. I have a jpg with the texture for the terrain, and another jpg with the height values (-1 to 1).

I've looked at various wrapper libraries (like SpiderGL and Three.js), but I can't find a sutable example, and if I do (like in Three.js) the code is not documented and I can't figure out how to do it.

Can anyone give me a good tutorial or example?

There is an example at Three.js http://mrdoob.github.com/three.js/examples/webgl_geometry_terrain.html which is almost what I want. The problem is that they create the colour of the mountains and the height values randomly. I want to read these values from 2 different image files.

Any help would be appriciated.
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无声情话 2024-12-14 23:46:32

在 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;
}

演示: https://web.archive.org/web/20220417041756/http://oos.moxiecode.com/js_webgl/terrain/index.html

Check out this post over on GitHub:

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

The example linked there by florianf helped me to be able to do this.

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;
}

Demo: https://web.archive.org/web/20220417041756/http://oos.moxiecode.com/js_webgl/terrain/index.html

偏爱自由 2024-12-14 23:46:32

我能想到的两种方法:

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

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

Two methods that I can think of:

  1. Create your landscape vertices as a flat grid. Use Vertex Texture Lookups to query your heightmap and modulate the height (probably your Y component) of each point. This would probably be the easiest, but I don't think browser support for it is very good right now. (In fact, I can't find any examples)
  2. Load the image, render it to a canvas, and use that to read back the height values. Build a static mesh based on that. This will probably be faster to render, since the shaders are doing less work. It requires more code to build the mesh, however.

For an example of reading image data, you can check out this SO question.

雨落□心尘 2024-12-14 23:46:32

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

You may be interested in my blog post on the topic: http://www.pheelicks.com/2014/03/rendering-large-terrains/

I focus on how to efficiently create your terrain geometry such that you get an adequate level of detail in the near field as well as far away.

You can view a demo of the result here: http://felixpalmer.github.io/lod-terrain/ and all the code is up on github: https://github.com/felixpalmer/lod-terrain

To apply a texture to the terrain, you need to do a texture lookup in the fragment shader, mapping the location in space to a position in your texture. E.g.

vec2 st = vPosition.xy / 1024.0;
vec3 color = texture2D(uColorTexture, st)
旧城空念 2024-12-14 23:46:32

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

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

Depending on your GLSL skills, you can write a GLSL vertex shader, assign the texture to one of your texture channels, and read the value in the vertex shader (I believe you need a modern card to read textures in a vertex shader but that may just be me showing my age :P )

In the vertex shader, translate the z value of the vertex based on the value read from the texture.

看轻我的陪伴 2024-12-14 23:46:32

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

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

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

Babylon.js makes this extremely easy to implement. You can see an example at:
Heightmap Playground

They've even implemented the Cannon.js physics engine with it, so you can handle collisions: Heightmap with collisions

Note: as of this writing it only works with the cannon.js physics plugin, and friction doesn't work (must be set to 0). Also, make sure you set the location of a mesh/impostor BEFORE you set the physics state, or you'll get weird behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文