'분류 전체보기'에 해당되는 글 40건

  1. 맵 생성기 1

    2024.03.25


이제 프랙탈 노이즈 효과 정도만 넣어주면 얼추 플러그인 작업도 완성이 되는데..
문제는 언리얼엔진 자체에 있는 Water 시스템의 Affact landscape 효과가 매우 무겁다는 것..

ocean / lake 의 경우 이 효과가 필요 없어서 크게 문제가 없는데 river 의 경우 없으면 강이 매우 어색하고 깨짐..
메모리 32GB 기준으로 1024 * 1024 사이즈까진 괜찮은데 그 이상부턴 과부하가 걸려서 제대로 적용이 불가능함 ㅠ

렉을 뚫고 기다려도 순간적으로 비디오 메모리 사용량도 엄청 먹어서 out of video memory 에러가 떠버리는데, 이건 머터리얼 텍스처 해상도를 낮은걸 사용하면 해결 될 것 같지만, 전자의 문제에서 이미 꺽여버린..

결국에는 강을 만들때 직접 자연스럽게 나오게끔 설정해야 되는데.. 이러면 또 River 쪽 소스코드를 뜯어봐야 할 예정


일단은 여기까지 만들고 개인사정으로 앞으론 조금식 업데이트 할 예정
그래도 끝이 다 온거 같은데 시간이 없어서 뭔가 찝찝하게 중도에 완료를 찍어버린 느낌

public 하기엔 에러 사항이 조금 많은 느낌..

blog image

Written by Pichachu


바다/호수 생성을 하고 강을 적용해야 하는데
사진은 임의로 강을 적용한 모습, 아직 어색하게 보임

호수의 깊이에 따라서 강이 적용되게끔 해야됨



강이 방향이 틀어지면 바깥쪽이 깊어지는 효과 비슷하게 주기 위해서 곡율에 따라서 강의 굵기 변화를 추가

기존에 이미지를 만들면 opengl에서는 겹치는 부분의 처리가 힘들어서 매우 이상하게 보였는데 좌/우로 선분을 추가로 만들어서 해결 


blog image

Written by Pichachu




바다 쪽은 Water는 임시로 CustomBody 으로 땜빵

실험적 플러그인이긴 하지만, 뭔가 버려진 느낌이 팍팍 드는..
버그가 엣날부터 있어 보이는데 수정을 안해주는..

하지만 기능이 딱 필요한거만 알차게 있어서 버리긴 어려운 ㅜ

Water 시스템이 Landscape 와 연동하여 자연스럽게 지형을 수정해주거나 하는데, 이게 연산 잡아먹는게 장난이 아니라 렉이 엄청 먹음(에디터에서 렘 사용량이 30기가를 훅훅 넘어감, 쉬핑하고는 안해봄)

이걸 끄러면 Affects Landscape 를 꺼줘야하는데 Spwan 하고 Affects Landscape 설정이 안먹혀서(꼼수가 있긴 하지만 landscape 에 대한 연산을 수행을 먼저 해버림), 블루프린트로 만들어서 미리 affects를 꺼쭌 class를 사용해야 됨

Ocean 쪽은 Affects 끄고 다시 적용을 시도해볼 예정..


강 부분 버그 수정 후 언리얼에 적용하고
지형 프렉탈이나 조금 더 자연스럽게 가다듬을 예정

blog image

Written by Pichachu


https://youtu.be/lAoHx1imwxA

바다쪽 해저 추가하고
Paint 칠 해주는 기능도 조금 추가하고
프텍탈 노이즈 넣어주면 일단 완성~

blog image

Written by Pichachu


후.. 얼추 이식 작업은 끝났고, 렌드스레이프 생성만 해주게끔 툴을 만들면 이식은 끝날 것 같네요 ㅎㅎ

컴파일러가 초기화되지 않은 변수를 자동으로 0으로 초기화 해버려서 깜박하고 초기화 하지 않은 곳에서 버그가 발생하고 이거 찾느냐 2~3일 시간이 날아갔네요 ㅠ

Initialize 호출 방식으로 초기화를 몇개 하다보니.. 으윽..


거기에 float/double 형 등 부동소숫점 연산에서 오차가 발생하기 마련인데
기존 프로젝트 셋팅이 잘못된건지 MS에서 VS 기본 설정을 이렇게 해둔건지 자동? 으로 반올림 하거나, 소수점 이하를 날려버리고 있더라구요;;

언리얼 프로젝트에선 어김없이 소숫점 단위로 연산이 튀어나와, 오차가 발생하기 시작했고
연산 결과가 너무 상이하게 나오는 참사가 발생.. 하나하나 반올림 넣어주고
티 많이 안나오는 곳은 풀어주고...

끄아아아아악


막코딩 하느냐 막 넣어버리거나 유니크용으로 일단 박고 시작한 전역 변수 diagram 쪽으로 다 밀어 넣어버리고..
랜덤 함수 부분도 변경해서, 0시드 모양이 바뀌었네요~

이 버그 덩어리를 아직 공개 상태로 안해둔게 다행 ㅎㅎ


현재 강 줄기가 이상하게 보이는 버그가 있는데, 이식이 일단 완료되면 이 버그부터 수정하고
바다 부분에 수위/심해 작업을 진행할 것 같네요

수위/심해 작업은 금방 할 수 있을 것 같은데.. 강줄기 버그가 문제네요 ㅠ

 

흐림 필터도 박스 필터랑 가우시안 필터 기능도 추가해두긴 했는데
어느 정도가 맵에 자연스럽게 적용되는진 실험을 해봐야해서 ㅎㅎ

거기에 프랙탈 노이즈도 넣어야하고.. 응애..

blog image

Written by Pichachu


 

 

예상하지 못했던 문제가 조금 있었는데

1. 높낮이 범위가 8비트가 아니라 16비트였다
2. 생각보다 각져있고, 꼭지점이 평평하다

사실 2번은 조금 의도하고 각지게 만든것도 있지만 XY 범위가 넓어서 그런 것 같기도 하고..
그 외에도 평평한 높이가 같은 셀들이 정점에 자주 만나서 평지가 되는 현상을 발견
전자는 스무스 필터를 넣어주면 대부분 해결되고, 후자는 최고점 봉우리의 경우 가중치를 추가로 넣던지 or 그냥 유지하던지 할 듯

스무스를 간단하게 넣어봤는데, 나름 괜찮게 나옴
스무스 알고리즘도 좀 찾아보고 추가로 프랙탈 노이즈를 넣어주면 은근 이쁘게 나오지 않을까 기대중입니다 ㅎㅎ



1번은 사실 언리얼엔진에 바로 이식하려고 생각하고 있어서 고려하지 않았는데 언리얼엔진이나 다른곳에 사용할 때 많이 불편해서 기능 추가, 언리얼엔진에 기본적으로 하이트맵 적용하는 기능이 있어서 사용해보니.. 상당히 깨져서 나옴 ㅠ
하이트맵이라 그냥 적당히 0~255 범위 정도면 충분할거라 생각했는데, 의외로 16비트(0~65535) 까지 사용하던..

그냥 Color에 grayscale용 uint16_t 변수 하나 만들고 이에 따라서 색 입혀주게끔 설정 끗~
시각용으로 컬러가 필요하긴 하니깐 Color 날려버리기도 애매..

blog image

Written by Pichachu


생각보다 시간이.. 너무 오래 걸렸다.. ㅜ

opengl 미리 보기

opgengl 실행에선 강과 계곡, 해안가 바다 최외각 셀은 임의로 색을 넣었습니다.
특히 최외각 부분은 색상 보정 할 필요가 없어보여서 안함 ㅋㅋㅋㅋ 그래서 개판입니다 ㅋㅋ

위의 2장은 모두 맵 타입을 섬으로 주고 생성한 이미지입니다.

맵 타입을 대륙으로 설정하고 뽑으면 가능한 뭉쳐서 나오게 셋팅 했습니다.
다만, 두 타입 모두 임의로 작은 섬들을 랜덤하게 만들게 하여 대륙에서도 섬들을 확인할 수 있습니다.


하이트맵




언리얼엔진에 사용하는게 목적인데, 빠르게 개발하기 위해서 opengl을 사용하여 제작했습니다.
사실 Fortune's algorithm 을 직접 구현하지 않고 깃허브에서 가져왔는데, 구현하신 분이 opengl를 사용하여 너무 잘 구현하셔서.. 겸사겸사 opengl을 그대로 사용했습니다 ㅎㅎ


언리얼 플러그인 제작 후 소스코드를 공개할지, 바로 공개할지 고민하고 있는데 사실상 미완성이긴 하니깐.. ㅋㅋ
아마 공개하면 MIT 라이센스로 오픈하지 않을까 생각중입니다.

현재 문제점이 10000개의 점을 사용하여 생성하면 5800X3D 기준 100ms 정도 걸리는데
비트맵으로 이미지 저장하는데 CPU 깡으로 저장하다 보니 200~300ms가 소요됩니다 ㅋㅋㅋㅋㅋㅋㅋ
멀티스레드나 gpu를 쓰게하면 될 것 같지만, gpu 쓰는법도 생소하고.. 스레드 지옥은 또 빠지기 싫고
무엇보다 귀찮네용 ㅎㅎ

아무튼 공유의 경우 Fortune's algorithm 구현한 코드가 MIT 라이센스로 공유되어 있는데, 사실 다른 라이센스였다~ 와 같은 대참사만 발생하지 않는다면 문제는 없어 보입니다~

blog image

Written by Pichachu

맵 생성기


인터넷에 Voronoi 알고리즘을 사용해서 맵 만드는 좋은 아이디어가 있길래 구현하는 중

강줄기, 도로를 추가하면 시스템의 기본적인 기능은 모두 구현 완료~

Height맵 등 이미지 저장 방식을 정하고(고도별로 색상 다른 부분을 그라데이션 처리), 바다의 해저 높낮이도 셋팅해주고
언리얼 엔진에 이식하면 시스템 기본은 완성

blog image

Written by Pichachu



1. 마칭큐브란?

The algorithm was developed by William E. Lorensen and Harvey E. Cline as a result of their research for General Electric. At General Electric they worked on a way to efficiently visualize data from CT and MRI devices. - wikipedia

대충 요약하면

General Electric 에서 CT와 MRI 장치들의 효과적인 시각화를 위한 연구결과로, William E. Lorensen 와 Harvey E. Cline 의해서 개발되었다.


그렇다, CT와 MRI 등의 의학 기기들에 적용하기 위해서 개발된 기술이란것을 알 수 있다.

그렇다면, 이 알고리즘이 무엇을 하길래 이런 의료기기에 적용한다는 걸까?


내용을 유추해본다면, CT 혹은 MRI등에서 무언가(사람, 동물 등)를 스캔하여 나온 데이터가 있을것이다.

근대 이것을 시각화 한다는게 무슨 소리일까?


카메라는 단순하게 보이는 그대로 찍는다. 그렇다고 카메라가 단순한 물건이라는 것은 아니다, 다만 사진은 보이는 그대로 단순하게 2차원으로 "찍는다".

이런 장비들은 단순하게 사진처럼 그대로 찍을 순 있지만, 여기서는 2차원 시각화가 아닌, 3차원 시각화를 하려는 것이다.



점이 모이면 선이되고, 선이 모이면 면이된다.

이런식으로 3D상에서 점(정육면체)을 이용해서 표현하는것을(마치 2D의 도트 그림 처럼, 사실 대부분의 이미지는 매우 작은 점으로 표현되어 있다) 복셀(Voxel) 이라고 한다.


복셀의 장점은, 해상도가 높을수록 매우 자연스럽다는것이다.(게임, 영화화 등에서 연기, 물 같은 효과를 리얼하게 주기위해서 복셀을 적용하는 경우가 많다)

단점은 간단하다, 연산량이 엄청나다.. 그렇다고 해상도를 낮추면 낮을수록 모양이 이상해진다.

2020년 지금의 기술로 일반 컴퓨터로는 연산량이 부족하다.


여기서 '마칭큐브'가 나온다.

복셀의 그래픽을, 우리가 흔히 쓰고있는 폴리곤 형식으로 바꾸는 것이다.


이해를 쉽게하기 위해서, 3차원이 아닌 2차원으로 생각해보자.


이런식으로 정사각형의 상자들로(도트) 좌표를 이룬다고 생각하자( 3차원에선 복셀 )

사진으로만 봐도, 도트의 해상도는 매우 낮다




그리고 어떠한 물체가, 빨간색 선 처럼 생겼다고 생각하자

이것을, 2차원 도트로 표현하자

표현 방법은, 사각형의 반절 이상을 차지하면, 파란색으로 칠한다.


이런 모양이 나올것이고, 여기서 한가지 문제에 직면한다.

"원형이랑 모양이 너무 다르잖아?"


위에서 말했던, 저 해상도 = 모양이 이상해진다 = 원형이랑 많이 다르다.

바로 이 문제가 발생하고, 이것을 해상도를 높이자니 3차원 환경에선 연산량이 감당을 못 한다.



그러면 어떻게 할까?

"마칭큐브" 알고리즘을 사용하면 된다.

드디어 마칭큐브 알고리즘을 본격적으로 알아볼 수 있겠다.


빨간색 선이 그리는 모양이 각 도트의 꼭짓점를 포함하면 동그라미를 쳐보자

추가로! 빨간색 선이 다음 사각형에 얼마나 가까워졌는지 값을 ISO 값이라고 하겠다

그리고 이 ISO값이 0.5 이상만 동그라미를 쳐주면 되겠다


(제일 위헤서, 우측 모서리에 동그라미를 깜박하고 안그렸다)

아마 사진을 보더라도 이해가 안될것이다, 그냥 넘어가자

다음 사진을 보면이해가 될 수 있을것이다.



이런식으로 점을 찍을 수 있을것이다.

그래서 저 점들을 이용해서 뭘 하려고?

선을 그려주자!( 3차원으로 말하자면 폴리곤을 만들어 주자! )


하나의 도트에 4개의 꼭짓점 있다.

각각의 도트에 찍힌 점의 갯수 및 모양에 따라 선을 그려주면 된다.



점 주변의 모서리 중앙에서, 점 주변의 각각의 모서리의 중앙을 대각선으로 선을 그려서 다이아몬드 모양으로 선을 그려준다.

점이 서로 붙어있다면, 일직선으로 선을 그려준다

점이 기준이 아닌, 도트를 기준으로 체크하는 방식이며, 도트의 꼭짓점 4개에 모두 점이 있다면, 선을 그리지 않는다.


하나의 꼭짓점만 점이 찍혀 있다면, 이 경우에 해당하는 대각선을 그려준다고 생각해보자.

꼭짓점에 2개, 3개의 점이 찍혀있다면, 이에 해당하는 그림을 그린다고 생각해보자.

이해가 안된다면 아래 사진을 보자.

이 사진은, 3개의 점이 찍혀있고, 각 도트가 꼭짓점에 찍힌 점의 갯수와 위치에 따라 선을 그린걸 표현한것이고

이해를 돕기위해, 도트마다 색을 넣어주었다.(선의 색갈도 맞추었다)


이런식으로, 도트의 각 꼭짓점에 찍힌 점의 갯수(위치)를 따라 선을 그려주는것이다.

그리고, 이 선을 그리는 경우의 수는

2 * 2 * 2 * 2 = 8 일 것이다! (2 ^ 4)


그러면, 이것을 리스트를 만들어서 정리할  수 있지 않을까?


좌측 하단의 꼭짓점이 1번

우측 하단의 꼭짓점이 2번

좌측 상단의 꼭짓점이 3번

우측 상단의 꼭짓점이 4번


이렇게 1, 2, 3, 4가 있다면

이것을 2진법으로 표현할 수 있다

0 0 0 0

좌측부터 1번 꼭짓점이라 하자


그러면, 사진의 파란색 도트의 경우에는

0 0 0 1

이렇게 표현 할 수 있다


=> 꼭짓점의 찍힌 위치에 및 갯수에 따라 숫자로 정의할 수 있다

=> 리스트를 만들면 도트의 꼭짓점 상태에 따라 해당하는 목록을 바로 찾을 수 있다!


즉, 마칭큐브는 룩업 테이블(리스트)를 만들어서, 복셀의 꼭짓점의 상태(위치와 갯수)에 따라 폴리곤을 어떻게 만들지 미리 계산해둔것이다.


참고로 3차원(복셀, 정육각형)의 꼭짓점은 8개 이므로, 마칭큐브의 경우의 수는 2^8 = 256 가지의 경위 수가 있다



그럼 다시 2차원으로 돌아와서, 아까의 빨간색 선을 마칭큐브 알고리즘을 이용하여 그려보자.


이런 모양이 나올것이고, 아래의 사진은 빨간색 선을 조금 수정하였다.


점이 하나 사라졌고, 그에 따른 선을 그렸다.





빨간선을 무식하게 도트 표현한것보다, 원형모양과 비슷하다.

즉, 저해상도 복셀에서도 폴리곤으로 원형과 비슷하게(상대적으로) 표현할 수 있다.



그리고, ISO값을 기억하는 사람이 있는가? 추가로 이해한 사람이 있는가?

이 ISO값에 따라서 대각선이 점에 더 가깝거나 멀게 그릴지 연산도 가능하다!

그냥 점에다가 ISO값을 기록하고, 선(폴리곤)을 그릴때 이것을 고려하여 그려주면 된다.


즉, 위에는 극단적으로, 점이 있음 or 없음 으로 2차원을 예시로 들었다. 그럼에도 상대적으로 도트로 표현한 것보다 상대적으로 원형에 가까웠다.

ISO 값을 이용하여 점에 더 가깝거나 멀게 그린다면? 더욱 더 원형에 가깝게 그릴 수 있을것이다.




미리 선(폴리곤)을 연산(저장)해서서 룩업 테이블에 저장해놔서, 선(폴리곤)을 그리는게 상대적으로 적은 연산이 들어간다. (도트에 점이 어떻게 찍혀있나 연산을 해주고, 룩업 테이블에서 해당 선(폴리곤)을 찾아 그려주면 끝난다)


이것을 사용하여, CT/MRI 에서도 적은 연산으로( 혹은 적은 데이터? )으로 원형과 비슷하게 3차원 그래픽으로 표현 할 수수 있다.


마칭큐브가 적용된 게임은, 흔히 이러한 특성 때문에 복셀 게임이라고 부르기도 한다(아마도ㅎ정확한건 모르겠다ㅎ)


대표적인 마칭큐브를 사용한 게임으로는 아스트로니어, 마인크래프트가 있겠다.

??? 마인크래프트는 정사각형 세계인데?!!, 이거 그냥 복셀만 사용해서 만든거 아니냐?


우리가 예시를 점의 유/무 에 따라서 극단적으로 그림을 그렸던것 처럼, 마인크래프트는 ISO값을 이용하여 더욱 더 극단적으로 연산한것이다.


추가로, 모든 꼭짓점에 점이 있으면, 선(폴리곤)을 그리지 않는것도 기억하는가?

순수한 복셀 그래픽은 모든곳에 박스를 표현하기 때문에, 연산량이 어마어마 하지만, 이러한 마칭큐브 특성 때문에, 안보이는곳은 연산을 하지 않는다!

아무튼, 약간의 꼼수지만, 마칭큐브를 이용해서 복셀을 구현?했다!

이러한 특성 때문에, 마인크래프트 처럼 마칭큐브가 적용된 게임을 복셀게임이라고 부른다.(아마도)


여담으로 마크에 대해서 좀 더 이야기 하자면

마인크래프트는 각 점에 추가로 블럭의 정보등을 담아서 블럭을 표현한것이다.

보통 컴퓨터는 무한한 숫자를 기록하는것은 매우 힘들기에, 매우 많은것을 넣어야 할 경우에는 약간의 꼼수를 부린다.

(연결 리스트라던지 기타 등등 있다)

마인크래프트의 경우에는, 청크 하나를 만들어서, 거기에 블록 여러개를 넣어버리는것이다.

즉, 마인크래프트는 청크 하나에 여러가지의 블록을 쑤셔 넣고 그것을 맵으로 구현한것이다.

맵을 이동하다보면, 로딩이 큐브 하나하나 되는것이 아니라, 큰 박스(청크) 단위로 로딩이 되는 이유다.




최근에 마칭큐브를 이용한 게임들이 은근 자주 보이고, "페리아 연대기" 라는 게임은 출시도 못하고 관짝에 들어가 버렸다. 엌ㅋㅋㅋ

마인크래프트만 보더라도 은근 오래된 게임이다. 즉, 게임에 적용되기 시작한지는 오래 되었다.


다만, 아직까지 컴퓨터로도 이런 꼼수?를 부려도 복셀을 구현하는것에 매우 큰 연산이 필요하므로..

최적화 병신이네 ㅋㅋㅋ 라는 타이틀을 가진 경우가 많다(마크는 자바로 만들어서 그냥 병신인것)



소스코드 예제는 다음시간에~
















blog image

Written by Pichachu


요즘 바빠서 이것저것 하다가 흐름이 끊겨서 한동안 안하다가 요즘 다시 시작

렌드스케이프 툴이랑 최대한 똑같이 만드려고 노력중

ㅋㅋㅋㅋ 아 맵 수정툴은 언제 만드나고 ㅋㅋㅋ

아 ㅋㅋㅋㅋㅋ 맵 무한 생성은 또 어떻게 만들어야 깔끔하려나!

blog image

Written by Pichachu