ฉันจะสร้างสัญญาณรบกวนที่เป็นรูปเป็นแผ่นสำหรับการสร้างแผนที่ได้อย่างไร


16

เฮ้พวกฉันกำลังพยายามหาวิธีสร้างเศษส่วนแบบเรียงต่อกันในรหัส (สำหรับแผนที่เกมแต่ไม่เกี่ยวข้อง ) ฉันพยายามแก้ไขปลั๊กอินเสียงรบกวนที่มาพร้อมกับ GIMP (ด้วยความเข้าใจที่ จำกัด อย่างมากเกี่ยวกับวิธีการ รหัสใช้งานได้) แต่ฉันไม่สามารถทำงานได้อย่างถูกต้อง

รหัสที่แก้ไขของฉันแล้ว (Java)

โมดูลเสียงรบกวนที่เป็นของแข็งของ GIMP ที่ฉันใช้เป็นรหัส (C)

นี่คือสิ่งที่ฉันพยายามที่จะบรรลุแต่ นี่คือสิ่งที่ฉันได้รับ

ดังนั้นถ้าใครสามารถเห็นสิ่งที่ฉันทำผิดหรือมีข้อเสนอแนะว่าฉันจะทำมันแตกต่างกันอย่างไรฉันก็จะขอบคุณมันมาก ขอบคุณล่วงหน้า. และถ้าฉันขอวิธีที่จะมากหรือถ้าเพียงแค่ความล้มเหลวอย่างมากในชีวิตฉันขอโทษ


ลองใช้การแก้ไข bicubic แทน bilinear หรือไม่ ฉันไม่รู้ว่านั่นเป็นปัญหาของคุณหรือไม่ แต่ดูเป็นอย่างนั้น
Stephen Furlani

คำตอบ:


4

ฉันไม่ได้ปฏิบัติตามรหัสของคุณอย่างแน่นอน แต่นี่เป็นคำอธิบายที่ง่ายขึ้นของอัลกอริทึมที่จะให้เอฟเฟกต์คร่าวๆ (ขึ้นอยู่กับภาพที่คุณโพสต์)

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

  1. สร้างเลเยอร์ของสัญญาณรบกวนแบบสุ่มที่เหมือนกัน (เลเยอร์พิกเซลแบบสุ่มพิกเซล)
  2. ตอนนี้สุ่มตัวอย่างแต่ละตัวด้วยการสุ่มตัวอย่างทุกพิกเซล, 1, 2, 4, 8, ... 2 ^ (n-1) พิกเซลและทำการแทรกพิกเซลกลาง แต่ละชั้นเรียบเนียนกว่าชั้นก่อนหน้า
  3. ตอนนี้ปรับสเกลเหล่านี้ด้วยค่า 1, 2, 4, 8, ฯลฯ แต่ละชั้นจะเข้มกว่าชั้นก่อนหน้า
  4. เพิ่มทั้งหมดเหล่านี้เข้าด้วยกัน
  5. ทำให้เป็นมาตรฐานด้วยการหารแต่ละพิกเซลด้วย (1 + 2 + 4 + 8 + ... 2 ^ (n-1))

ขั้นตอนที่ยากลำบากคือขั้นตอนการสุ่มตัวอย่างและการแก้ไข สมมติว่าเราอยู่ในเลเยอร์ที่ข้ามการสุ่มตัวอย่างทุกพิกเซล m-th นี่คือแนวคิดพื้นฐานสำหรับ m> 1 (ถ้า m คือ 1 เราจะใช้รูปภาพตามที่เป็น):

for each pixel x and y
   left_sample_coord = m *(x / m) //(integer division, automatically truncated)
   right_sample_coord = (left_sample_point + m) % image_width
   top_sample_point = m*(y / m) 
   bottom_sample_coord = (top_sample_point + m) % image_height

   horizontal_weight = (x - left_sample_point) / (m - 1)
   vertical_weight = (y - top_sample_point) / (m - 1)

   sample_top_left = image(left_sample_coord, top_sample_point)
   //and the same for the other four corners

   //now combine the top two points
   top_interpolate = sample_top_left * horizontal_weight + sample_top_right * (1-horizontal_weight)

  //now combine the bottom two points
  bottom_interpolate = sample_bottom_left * horizontal_weight + sample_bottom_right * (1-horizontal_weight)

  //and combine these two last obtained values

  smooth_noise(x, y) = top_interpolate * vertical_weight  + bottom_interpolate * (1 - vertical_weight)

เคล็ดลับ:

  • ผลลัพธ์ของอัลกอริทึมด้านบนอาจดูเล็กน้อย คุณสามารถลดเอฟเฟกต์นี้ได้โดยใช้เลเยอร์ของเสียงเดียวกันสำหรับทุกเลเยอร์หรือเพิ่มความเปรียบต่างให้กับภาพในภายหลัง
  • อัลกอริทึมด้านบนใช้การประมาณเชิงเส้น แต่การแก้ไขโคไซน์ (ทำการค้นหา) ให้ผลลัพธ์ที่ดีกว่ามาก
  • ทำให้เป็นไปได้ที่จะดูเลเยอร์ของคุณแยกกันระหว่างส่วนต่างๆของอัลกอริทึม สิ่งนี้จะช่วยให้คุณกำจัดข้อผิดพลาดได้อย่างรวดเร็ว

3

ดูเหมือนว่า Pastebin ดั้งเดิมของฉันหมดอายุแล้วดังนั้นฉันจึงไม่มีทางเปรียบเทียบโค้ดที่ใช้งานไม่ได้ แต่ในเกมปัจจุบันของฉันฉันได้อ่านและแปลรหัส GIMP เป็นภาษาจาวาอีกครั้งและดูเหมือนว่าจะทำงานได้ดีในขณะนี้

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

รหัส: http://pastebin.com/KsfZ99Xa

ตัวอย่าง: ตัวอย่างเครื่องกำเนิดไฟฟ้า perlin


2

เพียงแค่อ่านผ่านเวอร์ชั่น Java และ C และสังเกตเห็นความแตกต่างเล็กน้อยในวิธีที่คุณใช้ฟังก์ชั่นเสียงรบกวน นี่คือของคุณ:

int val = Math.abs((int) Math.floor(255.0 * noise(((double)col/(double)width), ((double)row/(double)height))));

รหัส C:

val = (guchar) floor (255.0 * noise ((col - xoffset) / width,

                                           (row - yoffset) / height));

ทำไมคุณถึงเลือกที่จะไม่ลบออฟเซ็ต (col - xoffset) และ (แถว - yoffset)

เพียงแค่สงสัย. ฉันไม่มีเวลาที่จะทำการวิเคราะห์รหัสอย่างสมบูรณ์

หวังว่านี่จะช่วยได้


xoffset และ yoffset เป็นการคำนวณวิธีที่ GIMP แบ่งรูปภาพออกเป็นกริด แต่โปรแกรมของฉันทั้งหมดทำงานบนไทล์เดียวดังนั้น x และ y offset จะเป็น 0
Nick Badal

2

ฉันไม่รู้ว่ามันจะช่วยได้หรือไม่ แต่เคล็ดลับต่อไปนี้ช่วยฉันได้:

http://www.gamedev.net/blog/33/entry-2138456-seamless-noise/

เพื่อนคนนี้ใช้ฟังก์ชั่นลดเสียงรบกวน 4 มิติและให้ค่า xy ของวงกลมสองวงเป็นค่า xyzw สำหรับเสียง 4d ผลที่ได้คือการวนลูปที่สมบูรณ์แบบ

นี่คือความคิด (ง่าย) สำหรับรูปภาพ 1000 * 1,000:

for(i = 0;i < 1000; i++){

  for(j = 0; j < 1000; j++){

    nx = cos((i/1000) * 2 * PI);
    ny = cos((j/1000) * 2 * PI);
    nz = sin((i/1000) * 2 * PI);
    nw = sin((j/1000) * 2 * PI);

    looped_noise = noise_4D( nx, ny, nz, nw, octaves, persistence, lacunarity, blah...);
    noise_buffer[(i*1000)+j] = looped_noise;

  }
}

1

ฉันแนะนำให้คุณใช้อัลกอริธึมแบบสี่เหลี่ยมจัตุรัสหรือที่เรียกว่าพลาสมาเศษส่วนหรือเศษส่วนการกระจัดกลางจุดแบบสุ่ม การใช้อัลกอริธึมนี้เป็นเรื่องง่ายที่จะ จำกัด ขอบให้มีค่าเท่ากัน เมื่อคุณสร้างค่าสำหรับขอบให้คัดลอกไปยังขอบที่สอดคล้องกันในอีกด้านหนึ่ง นี่เป็นแผนที่เรียงซ้อนที่สมบูรณ์แบบ


0

มีบทความที่ดีเกี่ยวกับการสร้างเสียงเป็นที่นี่ ไม่ใช่เสียงเพอร์ลินตามที่บทความอ้างว่า (เป็นเสียงสีชมพูจริง ๆ ) แต่ก็ยังมีประโยชน์อย่างมากที่จะเข้าใจวิธีสร้างภาพเสียงรบกวน

ดังนั้นเพื่อตอบคำถามของคุณจริง ๆ : เพื่อให้ได้ภาพที่เป็นรูปเป็นแผ่นคุณเพียงแค่ต้องรักษา "ความสามารถในการต่อเนื่อง" ไว้ได้ตลอดชั่วอายุคน นั่นคือเมื่อเสียงรบกวนคุณปรับให้เรียบราวกับว่ามันถูกทำซ้ำอย่างไม่สิ้นสุดในทุกทิศทาง - ปูกระเบื้อง


0

จากภาพหน้าจอฉันเดาว่ามีเพียงเลเยอร์ "ใหญ่" เท่านั้นที่ถูกสร้างขึ้นซึ่งเป็นสาเหตุที่เสียงรบกวนดังเกินไปและขาดรายละเอียด

สิ่งนี้อาจฟังดูโง่ แต่คุณลองเพิ่มตัวแปร "detail" (บรรทัดที่ 16) หรือไม่ ในรหัสของคุณตั้งค่าเป็น 1 ซึ่งหมายความว่าอัลกอริทึมจะสร้างรายละเอียดสองชั้นก่อนที่จะหยุด ลองเพิ่มเป็น 8 เช่น


0

คุณควรดูที่Simplex Noiseซึ่งพัฒนาโดย Ken Perlin เพื่อแก้ไขข้อบกพร่องของเสียง Perlin

ฉันทำงานเกี่ยวกับการใช้ Simplex Noise สำหรับเกม C ++ รองรับสัญญาณรบกวนหลายมิติ 1D / 2D / 3D / 4D ตอนนี้พื้นผิวในตัวเดียวคือหินอ่อน แต่คุณสามารถเพิ่มเพิ่มเติมได้อย่างง่ายดาย:

(http://code.google.com/p/battlestar-tux/source/browse/trunk/src/lib/procedural/)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.