2011-10-03 21 views
12

Estoy tratando de crear un terreno 3D usando WebGL. Tengo un jpg con la textura para el terreno y otro jpg con los valores de altura (-1 a 1).WebGL - Terreno con textura con heightmap

He visto varias bibliotecas contenedoras (como SpiderGL y Three.js), pero no puedo encontrar un ejemplo sustituible, y si lo hago (como en Three.js) el código no está documentado y puedo No descubra cómo hacerlo.

¿Alguien puede darme un buen tutorial o ejemplo?

Hay un ejemplo en Three.js http://mrdoob.github.com/three.js/examples/webgl_geometry_terrain.html que es casi lo que quiero. El problema es que crean el color de las montañas y los valores de altura aleatoriamente. Quiero leer estos valores de 2 archivos de imagen diferentes.

Cualquier ayuda se apruebe. Gracias

+0

Solo tenga en cuenta que JPEG puede no ser el mejor formato para un terreno ya que es con pérdidas, y los artefactos JPEG terminarán como golpes sutiles en el terreno que no esperaba encontrar. – izb

Respuesta

5

dos métodos que se me ocurre:

  1. crear sus vértices paisaje como una rejilla plana. Use Vertex Texture Lookups para consultar su altura y modular la altura (probablemente su componente Y) de cada punto. Esto probablemente sea el más fácil, pero no creo que el soporte del navegador sea muy bueno en este momento. (De hecho, no puedo encontrar ningún ejemplo)
  2. Cargue la imagen, rendericela en un lienzo y utilícela para volver a leer los valores de altura. Construye una malla estática basada en eso. Esto probablemente será más rápido de renderizar, ya que los sombreadores están haciendo menos trabajo. Sin embargo, requiere más código para construir la malla.

Para un ejemplo de lectura de datos de imagen, se puede extraer this SO question.

+1

La opción 2 funcionará mejor para usted en casi cualquier caso. La opción 1 solo es adecuada si lo que estás renderizando es solo el terreno, ya que todos los datos de elevación serán conocidos solo por el sombreador y necesitarás otros medios para ubicar (presumiblemente) otros objetos de escena. – Chiguireitor

12

Salida este post Más en GitHub:

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

El ejemplo los vinculados allí por florianf me ayudó a ser capaz de hacer esto

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

Demostración: http://oos.moxiecode.com/js_webgl/terrain/index.html

2

Usted puede estar interesado en mi blog sobre el tema: http://www.pheelicks.com/2014/03/rendering-large-terrains/

me centro en cómo crear de manera eficiente la geometría del terreno de tal forma que se obtiene un nivel adecuado de detalle en el campo cercano, así como a lo lejos.

Puede ver una demostración del resultado aquí: http://felixpalmer.github.io/lod-terrain/ y todo el código es hasta en github: https://github.com/felixpalmer/lod-terrain

para aplicar una textura al terreno, lo que necesita hacer una búsqueda de la textura en el fragmento de sombreado, la cartografía la ubicación en el espacio a una posición en su textura. P.ej.

vec2 st = vPosition.xy/1024.0; 
vec3 color = texture2D(uColorTexture, st) 
0

Dependiendo de sus habilidades GLSL, puede escribir un sombreado GLSL vértice, asignar la textura a uno de sus canales de textura, y lea el valor en el vertex shader (creo que necesita una tarjeta moderna para leer texturas en un sombreador de vértices, pero puede que solo yo muestre mi edad: P)

En el sombreado de vértices, traduzca el valor z del vértice en función del valor leído de la textura.

0

Babylon.js hace que esto sea extremadamente fácil de implementar. Se puede ver un ejemplo en: Heightmap Playground

Incluso han implementado el motor de física Cannon.js con ella, por lo que puede manejar las colisiones: Heightmap with collisions

Nota: Al escribir estas líneas, sólo funciona con el cañón El complemento de física .js y la fricción no funcionan (debe establecerse en 0). Además, asegúrese de establecer la ubicación de una malla/impostor ANTES de establecer el estado físico, o obtendrá un comportamiento extraño.

Cuestiones relacionadas