Tại sao tiếng ồn Perlin của tôi lại trông giống như một khối của người Do Thái?


21

Tôi đã cố gắng tự mình thực hiện tiếng ồn Perlin bằng cách sử dụng lý thuyết (theo flafla2.github.io/2014/08/09/perlinnoise.html). Thật không may, tôi không thể đạt được giao diện của tiếng ồn Perlin "nguyên bản".

Lý do nào khiến đoạn mã dưới đây biểu hiện một phiên bản khối của Perlin Noise?

Tôi nên cải thiện / thay đổi mã gì để nó tạo ra tiếng ồn Perlin mà không có các tạo tác?

Tôi nghi ngờ có thể có vấn đề trong cách tôi nội suy hoặc trong gradsvectơ. Các gradsvector chứa các sản phẩm chấm của (vector ngẫu nhiên cho điểm lưới) và (vector kích thước) - cho tất cả 4 điểm lân cận mạng. (Các vectơ ngẫu nhiên và kích thước được mô tả trong liên kết đầu tiên.)

Hộp cát GLSL: http://glslsandbox.com/e#32663.0

Hiện vật trong tiếng ồn

float fade(float t) { return t * t * t * (t * (t * 6. - 15.) + 10.); }
vec2 smooth(vec2 x) { return vec2(fade(x.x), fade(x.y)); }

vec2 hash(vec2 co) {
    return fract (vec2(.5654654, -.65465) * dot (vec2(.654, 57.4), co));
}

float perlinNoise(vec2 uv) {
    vec2 PT  = floor(uv);
    vec2 pt  = fract(uv);
    vec2 mmpt= smooth(pt);

    vec4 grads = vec4(
        dot(hash(PT + vec2(.0, 1.)), pt-vec2(.0, 1.)),   dot(hash(PT + vec2(1., 1.)), pt-vec2(1., 1.)),
        dot(hash(PT + vec2(.0, .0)), pt-vec2(.0, .0)),   dot(hash(PT + vec2(1., .0)), pt-vec2(1., 0.))
    );

    return 5.*mix (mix (grads.z, grads.w, mmpt.x), mix (grads.x, grads.y, mmpt.x), mmpt.y);
}

float fbm(vec2 uv) {
    float finalNoise = 0.;
    finalNoise += .50000*perlinNoise(2.*uv);
    finalNoise += .25000*perlinNoise(4.*uv);
    finalNoise += .12500*perlinNoise(8.*uv);
    finalNoise += .06250*perlinNoise(16.*uv);
    finalNoise += .03125*perlinNoise(32.*uv);

    return finalNoise;
}

void main() {
    vec2 position = gl_FragCoord.xy / resolution.y;
    gl_FragColor = vec4( vec3( fbm(3.*position) ), 1.0 );
}

Câu trả lời:


24

Nội suy có vẻ tốt. Vấn đề chính ở đây là hàm băm bạn đang sử dụng không tốt lắm. Nếu tôi chỉ nhìn vào một quãng tám và hình dung ra kết quả băm bằng cách xuất ra hash(PT).x, tôi nhận được một cái gì đó như thế này:

hàm băm xấu

Điều này được cho là hoàn toàn ngẫu nhiên trên mỗi ô vuông, nhưng bạn có thể thấy rằng nó có rất nhiều mẫu đường chéo trong đó (nó trông giống như một bàn cờ), vì vậy nó không phải là một hàm băm rất ngẫu nhiên và các mẫu đó sẽ xuất hiện trong tiếng ồn do nó tạo ra.

Vấn đề khác là hàm băm của bạn chỉ trả về các vectơ độ dốc trong [0, 1], trong khi chúng phải ở [−1, 1] để có được độ dốc theo mọi hướng. Đó là phần dễ dàng để sửa chữa bằng cách ánh xạ lại.

Để khắc phục những vấn đề đó, tôi đã chuyển mã sang sử dụng hàm băm này (mà tôi đã học được từ Mikkel Gjoel và có lẽ là do một bài báo của WJJ Rey ):

vec2 hash(vec2 co) {
    float m = dot(co, vec2(12.9898, 78.233));
    return fract(vec2(sin(m),cos(m))* 43758.5453) * 2. - 1.;
}

Lưu ý rằng do các chức năng trig, nó sẽ đắt hơn một chút so với phiên bản của bạn. Tuy nhiên, nó cải thiện đáng kể sự xuất hiện của tiếng ồn kết quả:

tiếng ồn fbm với chức năng băm tốt hơn


Cảm ơn bạn rất nhiều vì lời giải thích của bạn. Điều này có thể lạc đề, nhưng dù sao tôi cũng sẽ hỏi; trong một số mã nguồn tính toán nhiễu, người ta sử dụng vectơ vec3 (1, 57, 113) để tính toán sản phẩm chấm với tọa độ hiện tại (tôi cho rằng mục tiêu cũng là để có được hàm băm). Tại sao sự lựa chọn đặc biệt này của hằng số (57 xấp xỉ 1 radian theo độ, 133 = xấp xỉ 2 * radian tính theo độ)? Có phải vì tính tuần hoàn trong các chức năng trig? Tôi không thể google cái này.
saravati

3
@saravati Tôi không thực sự chắc chắn, nhưng một phỏng đoán là 57 và 113 được chọn vì chúng là số nguyên tố. (113 là số chính thành phần trong băm.
Nathan Reed

1
@cat Tôi nghi ngờ GLSL có PRNG, vì các chương trình GLSL mang tính quyết định.
user253751

1
Có vẻ như có một số câu hỏi mới tiềm năng trong chuỗi nhận xét này ...
trichoplax

1
Tôi đã có những tạo tác đó và hàm rand () này đã sửa nó. Vấn đề là sau khi tôi đi bộ như 2km trên địa hình của mình, các vật phẩm như OP bắt đầu xuất hiện trở lại. Nó đã sử dụng hàm băm ở đây: amindForverprogramming.blogspot.com/2013/07/ , điều đó đã khiến các cổ vật biến mất (Ngoại trừ ở khoảng cách 100km, bc không chính xác, nhưng không sao, tôi chỉ phải chia thành các khối và nhận được để làm việc bằng cách băm cả hai giá trị, điều này sẽ cho phép nhiễu perlin chạy gần như vô thời hạn). Vì vậy, tôi sẽ để điều này ở đây để có thể giúp đỡ bất cứ ai có cùng vấn đề.
Nicholas Pipitone
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.