맵 생성을 위해 타일 가능한 솔리드 노이즈를 어떻게 만듭니 까?


16

안녕하세요, 코드에서 타일 가능한 프랙탈을 생성하는 방법을 알아 내려고 노력 중입니다 (게임 맵 의 경우 관련이 없습니다 ) .GIMP와 함께 제공된 Solid Noise 플러그인을 수정하려고했습니다. 코드가 작동하지만 올바르게 작동하지 않습니다.

지금까지 수정 된 코드 (자바)

내 코드를 기반으로하는 김프의 견고한 노이즈 모듈 (C)

여기에 내가 달성하려고하는 것이 있지만 이것이 내가 얻는 것입니다.

그래서 누군가 내가 잘못한 것을 볼 수 있거나 다르게 수행하는 방법에 대한 제안이 있으면 크게 감사하겠습니다. 미리 감사드립니다. 그리고 인생에 많은 것을 요구하거나 인생에서 큰 실패를한다면 사과드립니다.


bilinear 대신 bicubic interpolation을 사용해보십시오 ? 나는 그것이 당신의 문제인지 전혀 모른다. 그러나 그것은 마치 좋아 보인다.
Stephen Furlani

답변:


4

코드를 정확하게 따르지는 않지만 다음은 효과를 대략적으로 달성하는 알고리즘에 대한 간단한 설명입니다 (게시 한 이미지를 기준으로 함).

다음 설명은 초 최적화 된 버전이 아니라 개념적으로 명확한 것입니다. 일단 실행하면 최적화 할 수 있습니다 (사실 실제로 크게).

  1. 균일 한 랜덤 노이즈의 n 개의 레이어를 생성합니다 (임의의 그레이 스케일 픽셀 만).
  2. 이제 1, 2, 4, 8, ... 2 ^ (n-1) 픽셀마다 샘플링하고 중간 픽셀을 보간하여 이들 각각을 샘플링하십시오. 각 레이어는 이전 레이어보다 부드럽습니다.
  3. 이제 1, 2, 4, 8 등의 계수로 이들의 스케일을 조정합니다. 각 레이어는 이전 레이어보다 어둡습니다.
  4. 이 모든 것을 함께 추가하십시오.
  5. 각 픽셀을 (1 + 2 + 4 + 8 + ... 2 ^ (n-1))로 나누어 정규화합니다.

어려운 단계는 샘플링 및 보간 단계입니다. m 번째 픽셀마다 샘플링을 건너 뛰는 레이어에 있다고 가정합니다. 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이 어떻게 든 만료 된 것처럼 보이므로 작동하지 않는 코드를 비교할 방법이 없지만 현재 게임에서 김프 코드를 다시 Java로 변환하여 정상적으로 작동하는 것 같습니다.

누구나이 코드를 사용하려는 경우 생성자를 수정하여 설정 매개 변수 (세부 사항 및 크기)를 수정하여 원하는 방식으로 작동하도록하는 것이 좋습니다. 편집 : 내 원래의 질문은 그것을 타일 가능하게 만드는 것에 관한 것이라는 것을 깨달았으므로 tilable을 true로 설정해야합니다!

코드 : http://pastebin.com/KsfZ99Xa

예: 펄린 발전기 예


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) 및 (row-yoffset)

궁금해 코드를 완전히 분석 할 시간이 없습니다.

도움이 되었기를 바랍니다.


xoffset과 yoffset은 김프가 이미지를 격자로 나누는 방식으로 계산하지만, 프로그램은 모두 하나의 타일에서 작동하므로 x와 y 오프셋은 0이됩니다.
Nick Badal

2

그것이 도움이 될 수 있는지 모르겠지만 다음 트릭은 나를 위해 대접했습니다.

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

이 동료는 4d 노이즈 기능을 사용하고 있으며 단순히 두 원의 xy 값을 4d 노이즈의 xyzw 값으로 제공합니다. 결과는 완벽하게 반복됩니다.

1000 * 1000 사진에 대한 아이디어는 다음과 같습니다.

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

노이즈 생성에 관한 훌륭한 기사가 있습니다 . 기사에서 주장하는 것처럼 Perlin 노이즈는 아니지만 (실제로 핑크 노이즈) 노이즈 이미지가 생성되는 방식을 이해하는 것이 여전히 유용합니다.

따라서 실제로 질문에 답하려면 타일 가능한 노이즈 이미지를 만들려면 세대 전체에 걸쳐 "타일 성"을 유지하면됩니다. 즉, 노이즈가 스무딩되면 모든 방향으로 무한 반복되는 것처럼 매끄럽게 다듬습니다.


0

스크린 샷에서, "큰"레이어 만 생성되는 것 같아서 잡음이 너무 규칙적으로 나타나고 디테일이 부족합니다.

어리석게 들릴지 모르지만 "세부 사항"변수를 늘리려 고 했습니까 (16 행)? 코드에서 1로 설정됩니다. 즉, 알고리즘은 중지하기 전에 두 계층의 세부 정보 만 생성합니다. 8과 같이 늘리십시오.


0

또한 Perlin 노이즈의 단점 중 일부를 해결하기 위해 Ken Perlin이 개발 한 Simplex Noise를 살펴보십시오 .

C ++ 게임을위한 Simplex Noise 구현을 연구하고 있습니다. 멀티 옥타브 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.