ทำไมเสียงเพอร์ลินของฉันจึงดู“ บล็อก”?


21

ฉันพยายามใช้ Perlin Noise ด้วยตัวเองโดยใช้เพียงทฤษฎี (ติดตาม flafla2.github.io/2014/08/09/perlinnoise.html) น่าเสียดายที่ฉันไม่สามารถมองหาเสียงเพอร์ลิน "ดั้งเดิม" ได้

อะไรคือสาเหตุที่รหัสด้านล่างแสดงผล Perlin Noise รุ่นที่บล็อก

ฉันควรปรับปรุง / เปลี่ยนแปลงรหัสเพื่อให้แสดงผล Perlin Noise โดยไม่มีสิ่งประดิษฐ์หรือไม่

ฉันสงสัยว่าอาจมีปัญหาไม่ว่าจะเป็นวิธีการสอดแทรกหรือในgradsเวกเตอร์ gradsเวกเตอร์มีผลคูณจุดของ (เวกเตอร์สุ่มสำหรับจุดตาข่าย) และ (เวกเตอร์ขนาด) - ทั้ง 4 จุดขัดแตะอยู่บริเวณใกล้เคียง (เวกเตอร์สุ่มและขนาดอธิบายไว้ในลิงค์แรก)

GLSL Sandbox: http://glslsandbox.com/e#32663.0

สิ่งประดิษฐ์ในเสียง

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

คำตอบ:


24

การแก้ไขดูดี ปัญหาหลักที่นี่คือฟังก์ชั่นแฮชที่คุณใช้ไม่ดีมาก ถ้าฉันดูเพียงหนึ่งอ็อกเทฟและเห็นภาพผลแฮชโดยเอาท์พุhash(PT).xทฉันจะได้สิ่งนี้:

ฟังก์ชั่นแฮชที่ไม่ดี

นี่ควรจะเป็นแบบสุ่มทั้งหมดต่อตารางสแควร์ แต่คุณสามารถเห็นว่ามันมีรูปแบบเส้นทแยงมุมจำนวนมากอยู่ในนั้น (มันเกือบจะดูเหมือนกระดานหมากรุก) ดังนั้นจึงไม่ใช่แฮชแบบสุ่มมากและรูปแบบเหล่านั้นจะปรากฏใน เสียงที่เกิดจากมัน

อีกปัญหาหนึ่งคือแฮชของคุณจะคืนค่าเวกเตอร์ไล่ระดับใน [0, 1] ในขณะที่พวกเขาควรอยู่ใน [−1, 1] เพื่อให้ได้การไล่ระดับสีในทุกทิศทาง ส่วนนั้นง่ายต่อการแก้ไขโดยทำการแมปใหม่

เพื่อแก้ไขปัญหาเหล่านั้นฉันเปลี่ยนรหัสเพื่อใช้ฟังก์ชันแฮชนี้ (ซึ่งฉันได้เรียนรู้จาก Mikkel Gjoel และอาจเป็นเพราะกระดาษโดย 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.;
}

โปรดทราบว่าเนื่องจากฟังก์ชันตรีโกณอาจมีราคาแพงกว่ารุ่นของคุณเล็กน้อย อย่างไรก็ตามมันช่วยปรับปรุงลักษณะที่ปรากฏของเสียงที่เกิด:

เสียง fbm พร้อมฟังก์ชันแฮชที่ดีขึ้น


ขอบคุณมากสำหรับคำอธิบายของคุณ นี่อาจเป็นหัวข้อนอกเรื่อง แต่ฉันจะถามต่อไป ในบางซอร์สโค้ดที่คำนวณเสียงผู้คนใช้เวกเตอร์ vec3 (1, 57, 113) เพื่อคำนวณหาจุดของผลิตภัณฑ์ด้วยพิกัดปัจจุบัน (ฉันคิดว่าเป้าหมายคือเพื่อรับแฮชด้วย) ทำไมค่าคงที่ตัวเลือกนี้โดยเฉพาะ (57 มีค่าประมาณ 1 เรเดียนเป็นองศา 133 = ประมาณ 2 * เรเดียนเป็นองศา) เป็นเพราะช่วงเวลาในฟังก์ชั่นตรีโกณมิติ? ฉันไม่สามารถ google สิ่งนี้
sarasvati

3
@sarasvati ฉันไม่แน่ใจจริงๆ แต่เดาว่าเลือก 57 และ 113 เพราะพวกเขาเป็นตัวเลขที่สำคัญ (113 เป็นไพร์ม; 57 ไม่ได้ แต่มันคือ 3 * 19 ดังนั้นยังคงดีกว่า ... ถ้าเป็นอย่างนั้น) การทวีคูณหรือการดัดแปลงโดยหมายเลขไพร์ม - ไอมีแนวโน้มที่จะทำให้ชิ้นส่วนแตกต่างกันดังนั้นจึงไม่ใช่เรื่องแปลก ส่วนผสมในแฮช
นาธานรีด

1
@cat ฉันสงสัยว่า GLSL มี PRNG เนื่องจากโปรแกรม GLSL นั้นถูกกำหนดไว้แล้ว
user253751

1
ดูเหมือนว่ามีหลายคำถามใหม่ที่มีศักยภาพในหัวข้อความคิดเห็นนี้ ...
Trichoplax

1
ฉันมีสิ่งประดิษฐ์เหล่านั้นและฟังก์ชั่น rand () นี้แก้ไข ปัญหาคือหลังจากที่ฉันเดินเช่น 2km ในภูมิประเทศของฉันสิ่งประดิษฐ์เช่น OPs เริ่มปรากฏขึ้นอีกครั้ง มันใช้ฟังก์ชั่นแฮชที่นี่: amindforeverprogramming.blogspot.com/2013/07/ …ที่ทำให้สิ่งประดิษฐ์หายไป (ยกเว้นที่ระยะทาง 100km, bc of imprecision แต่ไม่เป็นไรฉันแค่ต้องแยกออกเป็นชิ้น ๆ และได้สิ่งนั้นมา ในการทำงานโดยการ hashing ค่าทั้งสองซึ่งจะช่วยให้เสียง perlin ทำงานเกือบไม่มีกำหนด) ดังนั้นฉันจะออกจากที่นี่เพื่อช่วยทุกคนที่มีปัญหาเดียวกัน
Nicholas Pipitone
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.