WebGL - Textured terrain with heightmap

前端 未结 5 1597
滥情空心
滥情空心 2020-12-31 08:23

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 vari

相关标签:
5条回答
  • 2020-12-31 08:39

    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.

    0 讨论(0)
  • 2020-12-31 08:40

    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: http://oos.moxiecode.com/js_webgl/terrain/index.html

    0 讨论(0)
  • 2020-12-31 08:41

    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)
    
    0 讨论(0)
  • 2020-12-31 08:55

    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.

    0 讨论(0)
  • 2020-12-31 09:04

    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.

    0 讨论(0)
提交回复
热议问题