WebGL - текстурированная местность с картой высот - PullRequest
12 голосов
/ 03 октября 2011

Я пытаюсь создать трехмерную местность, используя WebGL. У меня есть JPG с текстурой для местности, а другой JPG со значениями высоты (от -1 до 1).

Я просмотрел различные библиотеки-оболочки (например, SpiderGL и Three.js), но не могу найти подходящий пример, и если я это сделаю (как в Three.js), код не документируется, и я могу не могу понять, как это сделать.

Кто-нибудь может дать мне хороший учебник или пример?

Есть пример на Three.js http://mrdoob.github.com/three.js/examples/webgl_geometry_terrain.html, который почти то, что я хочу. Проблема в том, что они создают цвет гор и значения высоты случайным образом. Я хочу прочитать эти значения из 2 разных файлов изображений.

Любая помощь будет оценена. Спасибо

Ответы [ 5 ]

12 голосов
/ 09 мая 2012

Проверьте этот пост на 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

5 голосов
/ 04 октября 2011

Два метода, которые я могу придумать:

  1. Создайте вершины вашего ландшафта в виде плоской сетки.Используйте Vertex Texture Lookups для запроса карты высот и модулирования высоты (вероятно, вашего компонента Y) каждой точки.Это, вероятно, будет самым простым, но я не думаю, что поддержка браузера для него сейчас очень хорошая.(На самом деле я не могу найти никаких примеров)
  2. Загрузить изображение, отобразить его на холсте и использовать его для считывания значений высоты.Построить статическую сетку на основе этого.Это, вероятно, будет быстрее отображаться, поскольку шейдеры выполняют меньше работы.Однако для построения сетки требуется больше кода.

Для примера чтения данных изображения вы можете проверить этот вопрос SO.

2 голосов
/ 28 мая 2014

Вас может заинтересовать мой пост в блоге на тему: 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)
1 голос
/ 22 июля 2014

В зависимости от ваших навыков GLSL, вы можете написать вершинный шейдер GLSL, назначить текстуру одному из ваших текстурных каналов и прочитать значение в вершинном шейдере (я считаю, что вам нужна современная карта для чтения текстур в вершинном шейдерено это может быть просто мой возраст: P)

В вершинном шейдере переведите значение z вершины на основе значения, считанного из текстуры.

0 голосов
/ 13 января 2017

Babylon.js делает это чрезвычайно простым в реализации.Вы можете увидеть пример по адресу: Карта высот

Они даже реализовали физический движок Cannon.js, поэтому вы можете обрабатывать коллизии: Карта высот с коллизиями

Примечание: на момент написания статьи он работал только с физическим плагином cannon.js и трение не работало (должно быть установлено на 0).Кроме того, убедитесь, что вы установили местоположение меша / самозванца, ДО того, как вы установите физическое состояние, или вы получите странное поведение.

...