Các cạnh ồn ào, làm nhẵn các cạnh giữa các mặt thông qua shader mảnh


8

Tôi có một địa hình được tạo, với hình dạng lục giác, theo ảnh chụp màn hình bên dưới:

nhập mô tả hình ảnh ở đây

Sau đó tôi tạo ra các quần xã, nhưng như bạn có thể thấy các đường viền giữa chúng thực sự xấu xí và thẳng. Để che giấu nguồn gốc hình lục giác đó, tôi sẽ cần phải làm mịn các đường viền giữa các quần xã. Đây là cách nó trông giống như trong khung dây với khuôn mặt hình tam giác thực sự:

nhập mô tả hình ảnh ở đây

Những gì tôi đang hướng tới là một cái gì đó giống như thế này:

nhập mô tả hình ảnh ở đây

Mỗi đỉnh có cấu trúc giữ kiểu quần xã, tôi cũng có thể thêm các thuộc tính đặc biệt vào các đỉnh ở cạnh giữa hai quần xã, nhưng dường như tôi không thể tìm ra cách loại bỏ mã này trong mã shader, rõ ràng là nhiễu có liên quan ở đây, nhưng làm thế nào để tôi làm cho nó liên tục trên nhiều mặt và toàn bộ đường viền của nhiều quần xã?

Tôi đang kết xuất với WebGL bằng THREE.js


Bạn đã thử MSAA?
Milo Lu

@Milo Bạn đã thử đọc câu hỏi chưa?
Bálint

Làm thế nào để bạn gửi thông tin biome cho shader?
Bálint

@ Bálint Biome Ngay bây giờ tôi chuyển màu qua thuộc tính đỉnh, khi tôi thực sự lấy mẫu màu từ họa tiết thực, thay vì màu đơn giản, tôi sẽ chuyển loại biome thành số nguyên.
dùng1617735

Các thuộc tính của Vertex không thể được sử dụng như bạn muốn, nếu bạn chuyển sang kết cấu, việc này sẽ dễ dàng hơn rất nhiều. Tải lên thông tin quần xã dưới dạng kết cấu, do đó bạn sẽ có thể nhận được quần xã sinh vật gần đó
Bálint

Câu trả lời:


9

Các câu trả lời khác ở đây đề nghị sử dụng một kết cấu. Đây là một kỹ thuật không sử dụng kết cấu.

Bạn muốn ranh giới giữa các hình lục giác trở nên thú vị. Sẽ dễ dàng hơn để tạo ranh giới thú vị khi bạn di chuyển chúng vào trung tâm của những gì bạn đang vẽ. Thay vì vẽ các ô trực tiếp, bạn vẽ các hình nền kép của gạch. Kỹ thuật này được gọi là góc góc gạch ốp tường ( ở đâyở đâyở đây ). Hình kép của hình lục giác là hình tam giác, vì vậy chúng tôi sẽ vẽ những hình tam giác này thay vì hình lục giác:

tam giác kép của một hình lục giác

Ranh giới giữa các hình lục giác hiện ở giữa các hình tam giác được hiển thị, vì vậy điều đó sẽ cho phép chúng tôi làm những điều thú vị hơn với chúng. Phần thưởng: bạn chỉ cần vẽ hai hình tam giác trên mỗi hình lục giác, thay vì sáu (hoặc hai mươi bốn như bạn đang làm bây giờ).

Bên trong mỗi hình tam giác đó, chúng tôi muốn shader mảnh để vẽ các hình lục giác. Chúng ta có thể làm điều đó với tọa độ barycentric . Đặt (1,0,0), (0,1,0) và (0,0,1) tại mỗi đỉnh của tam giác. Bên trong tam giác, các tọa độ đó sẽ được nội suy. Shader mảnh sẽ nhận được (a, b, c) và có thể xem để xem giá trị nào lớn nhất - sẽ cho chúng ta biết nên vẽ hình lục giác nào trong ba hình lục giác tại thời điểm này.

float max_n = max(barycentric.r, max(barycentric.g, barycentric.b)); if (max_n == barycentric.r) { color = v_color0; } else if (max_n == barycentric.g) { color = v_color1; } else if (max_n == barycentric.b) { color = v_color2; }

Đó là cho các đường thẳng.

Nếu bạn muốn các cạnh nhiễu, bạn có thể thêm nhiễu vào tọa độ barycentric:

hình lục giác với các cạnh ồn

Bằng cách chơi với bước sóng / tần số biên độ nhiễu, bạn có thể nhận được một số hiệu ứng thú vị:

hình lục giác với các cạnh thậm chí ồn hơn

Bạn cần cẩn thận với tiếng ồn, đảm bảo nó nhất quán trên các ranh giới tam giác. Một cách để làm điều đó là truyền vào id hex và sử dụng giá trị đó làm giá trị hạt giống cho mỗi trong ba giá trị nhiễu được thêm vào tọa độ barycentric.

Tôi đã làm một bản demo tương tác ở đây . (Đối với bản demo tôi đã không triển khai id hex hoặc một số thứ khác bạn có thể cần nếu bạn thực hiện công việc này trong một dự án thực tế - đó chỉ là bản demo nhanh & bẩn)


Bây giờ đó là một số tài liệu trả lời chất lượng hàng đầu.
Quentin

Câu trả lời chính xác! Chỉnh sửa tinh tế: đa giác thông thường, bao gồm cả hình lục giác, là tự kép. Tuy nhiên, tessellations của tam giác và hình lục giác là cá nhân nộp thuế của nhau, như câu trả lời của bạn minh họa.
Erik Foss

0

Tôi chắc chắn rằng "có thể" được giải quyết bằng một số thuật toán hình ảnh nhưng nếu là tôi thì có lẽ tôi sẽ giải quyết nó bằng kết cấu. Tôi sẽ tạo họa tiết hình lục giác, đặt tất cả chúng vào một tập bản đồ kết cấu, sau đó cho mỗi hình lục giác tôi nhìn vào hàng xóm của nó và quyết định áp dụng kết cấu nào.

Các kết cấu sẽ cần phải có các phiên bản cho từng loại địa hình cộng với các phiên bản cho từng loại chuyển đổi.

Điều này tương tự như có bao nhiêu hệ thống dựa trên gạch làm địa hình. Đây là một ví dụ từ các trò chơi 2d .

Một khả năng khác là chỉ cần có kết cấu cho các loại địa hình khác nhau của bạn (nước, tuyết, bụi bẩn, cỏ) và thêm số lượng hỗn hợp vào từng đỉnh của hình lục giác để quyết định cách trộn chúng.

Bài viết này cho thấy ý tưởng pha trộn kết cấu địa hình. Tôi không đề xuất theo dõi việc thực hiện của họ nhưng nó cho thấy ý tưởng.


Chà, trong trường hợp của tôi, việc chuẩn bị họa tiết không đơn giản, vì hình lục giác không đồng nhất, hình dạng và kích thước khác nhau trên toàn bản đồ. Thật không may, đó là cái giá tôi phải trả cho việc có một hành tinh, không chỉ bản đồ phẳng. Ngoài ra bài viết có vẻ rất im lặng, cảm ơn. Mặc dù trong trường hợp của tôi, tôi đang hiển thị địa hình từ trên cao, có lẽ từ độ cao, ví dụ, bạn không thể thấy một cây duy nhất và toàn bộ khu rừng trông giống như một khối greem.
dùng1617735

0

Đầu tiên, làm cho quần xã của bạn thành một kết cấu. Ánh xạ các hình tam giác vào texcoords. Bạn có thể làm điều này bằng cách sử dụng phép chiếu hình chiếu, hoặc, tốt hơn là bản đồ khối . Bây giờ, trong shader mảnh, làm một cái gì đó như thế này:

// frequency and magnitude of the noise in texels.
uniform float frequency;
uniform float magnitude;

// This function should just look like random smooth noise in x,y
// This one isn't great, but you can experiment.
vec2 noise(vec3 vertexPos) {
    return vec2(sin(vertexPos.x * frequency + vertexPos.y * frequency) * magnitude, 
                cos(vertexPos.y * frequency * 2 + vertexPos.z * frequency) * magnitude);
}

// Sample the texture and preturb it with noise based on the world
// position of the fragment.
vec4 frag(vec2 texCoord, vec3 fragmentPos) {
   return texture(mySampler, texCoord + noise(fragmentPos));
}

trong đó noisemột số hàm giả ngẫu nhiên (sử dụng, ví dụ: sin) trên vị trí 3D của đỉnh trong không gian mô hình sẽ trả về phần bù nhiễu cho tọa độ kết cấu. Lấy mẫu kết cấu bằng cách GL_NEARESTgiữ đường viền sắc nét.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.