2011-10-03 27 views
12

Tôi đang cố gắng tạo địa hình 3D bằng WebGL. Tôi có một jpg với kết cấu cho địa hình và một jpg khác với các giá trị độ cao (-1 đến 1).WebGL - Địa hình được kết cấu có chiều cao

Tôi đã xem các thư viện trình bao bọc khác nhau (như SpiderGL và Three.js), nhưng tôi không thể tìm thấy ví dụ có thể sutable và nếu tôi làm (như trong Three.js) mã không được ghi lại và tôi có thể 't tìm ra cách để làm điều đó.

Có ai có thể cho tôi một hướng dẫn hay ví dụ hay không?

Có một ví dụ tại Three.js http://mrdoob.github.com/three.js/examples/webgl_geometry_terrain.html gần như là những gì tôi muốn. Vấn đề là họ tạo ra màu sắc của các ngọn núi và các giá trị chiều cao một cách ngẫu nhiên. Tôi muốn đọc các giá trị này từ 2 tệp hình ảnh khác nhau.

Bất kỳ trợ giúp nào sẽ được đánh giá cao. Cảm ơn

+0

Chỉ cần lưu ý rằng JPEG có thể không phải là định dạng tốt nhất cho địa hình vì nó mất dữ liệu và các tạo phẩm JPEG sẽ kết thúc dưới dạng các vệt nhỏ trong địa hình mà bạn có thể không mong đợi. – izb

Trả lời

5

Hai phương pháp mà tôi có thể nghĩ đến:

  1. Tạo đỉnh phong cảnh của bạn như là một mạng lưới phẳng. Sử dụng Vertex Texture Lookups để truy vấn chiều cao và điều chỉnh chiều cao (có thể là thành phần Y của bạn) của mỗi điểm. Điều này có lẽ là dễ nhất, nhưng tôi không nghĩ rằng hỗ trợ trình duyệt cho nó là rất tốt ngay bây giờ. (Trên thực tế, tôi không thể tìm thấy bất kỳ ví dụ nào)
  2. Tải hình ảnh, hiển thị hình ảnh đó lên canvas và sử dụng để đọc lại giá trị độ cao. Xây dựng một lưới tĩnh dựa trên đó. Điều này có thể sẽ nhanh hơn để render, vì các shader đang làm ít công việc hơn. Nó đòi hỏi nhiều mã hơn để xây dựng lưới, tuy nhiên.

Đối với một ví dụ về đọc dữ liệu hình ảnh, bạn có thể kiểm tra this SO question.

+1

Tùy chọn 2 sẽ hoạt động tốt hơn cho bạn trong mọi trường hợp. Tùy chọn 1 chỉ phù hợp nếu những gì bạn đang vẽ chỉ là địa hình, bởi vì tất cả dữ liệu độ cao sẽ được chỉ biết bởi trình đổ bóng và bạn sẽ cần một số phương tiện khác để định vị các đối tượng cảnh khác (có lẽ) của bạn. – Chiguireitor

12

Check-out này gửi qua trên GitHub:

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

Ví dụ liên kết đó bằng florianf giúp tôi trở thành có thể làm điều này.

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

2

Bạn có thể quan tâm đến bài viết trên blog của tôi về chủ đề này: http://www.pheelicks.com/2014/03/rendering-large-terrains/

tôi tập trung vào làm thế nào để tạo ra hiệu quả hình học địa hình của bạn như vậy mà bạn nhận được một mức độ đầy đủ chi tiết trong lĩnh vực gần cũng như xa.

Bạn có thể xem một bản demo của kết quả ở đây: http://felixpalmer.github.io/lod-terrain/ và tất cả các mã lên trên github: https://github.com/felixpalmer/lod-terrain

Để áp dụng một kết cấu địa hình, bạn cần phải làm một tra cứu kết cấu trong fragment shader, lập bản đồ vị trí trong không gian cho một vị trí trong kết cấu của bạn. Ví dụ.

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

Tùy thuộc vào kỹ năng GLSL của bạn, bạn có thể viết một Shader GLSL đỉnh, chuyển nhượng kết cấu với một trong các kênh truyền hình kết cấu của bạn, và đọc giá trị trong vertex shader (Tôi tin rằng bạn cần một thẻ hiện đại để đọc textures trong bóng đổ đỉnh nhưng điều đó có thể chỉ cho tôi thấy tuổi của tôi: P)

Trong bóng đổ đỉnh, dịch giá trị z của đỉnh dựa trên giá trị được đọc từ kết cấu.

0

Babylon.js làm việc này cực kỳ dễ thực hiện. Bạn có thể xem một ví dụ tại địa chỉ: Heightmap Playground

Họ thậm chí đã thực hiện động cơ vật lý Cannon.js với nó, vì vậy bạn có thể xử lý va chạm: Heightmap with collisions

Lưu ý: vào thời điểm này viết nó chỉ làm việc với các pháo Plugin vật lý .js và ma sát không hoạt động (phải được đặt thành 0). Ngoài ra, hãy chắc chắn rằng bạn thiết lập vị trí của một lưới/impostor TRƯỚC KHI bạn thiết lập trạng thái vật lý, hoặc bạn sẽ nhận được hành vi kỳ lạ.

Các vấn đề liên quan