반응형

 

 

 

 

이전에 C로 퀵정렬을 구현한 글을 썼었는데, 육안으로 과정이 보이는 글이 아닌 코드만 작성되어있는 글이어서 유니티 C#으로 퀵 정렬 과정을 육안으로 확인할 수 있도록 제작해봤다.

만들면서 파티션 정렬하는 과정에서 high index가 파티션 배열의 범위를 벗어나는 버그가 있었는데, 단순히 조건문 순서상의 오류라 바로 수정했다. (생각보다 그 글이 조회수가 좀 됐는데, 글을 보신 분들이 문제 제기를 안했다는게 의아함)

 

 

 

 

1. 유니티 C# 퀵정렬 프로젝트

- 코드가 아닌 유니티 프로젝트로 올립니다. (깃허브)

 

GitHub - realnity09/QuickSort_CS

Contribute to realnity09/QuickSort_CS development by creating an account on GitHub.

github.com

 

 

 

 

2. QuickSort 컴포넌트 설명

- TargetArrSize : 배열의 길이를 지정할 수 있다.

- Min, Max : 배열 요소의 최소값과 최대값. (지정한 범위 안에서 랜덤 함수로 지정된다.)

- Delay : 정렬하는 속도 (값이 높을수록 느려집니다. WaitForSeconds값.)

※ Scene에 버튼 2개가 붙어있는데, Create arr 버튼으로 배열을 생성하고, Quick sort 버튼을 누르면 정렬이 시작되며 정렬 과정을 눈으로 확인할 수 있습니다.

low index - Red, high index - Blue, pivot index - cyan

※ 정렬이 완료되면 UI element가 초록색으로 변합니다.

 

 

 

3. 퀵정렬 설명

 

퀵정렬(Quick Sort) 구현

퀵정렬(Quick Sort) - 찰스 앤터니 리처드 호어가 개발한 알고리즘이다. - 평균 O(n log n)으로 매우 빠른 정렬속도를 자랑한다. - 기준(Pivot) 값을 기준으로 나머지 원소에 대해 대소관계를 비교하여 큰

srdeveloper.tistory.com

 

 

 

 

 

 

반응형

'Stack > Algorithm' 카테고리의 다른 글

문자열, 숫자 뒤집기  (0) 2021.10.16
퀵정렬(Quick Sort) 구현  (0) 2021.09.19
삽입정렬(Insertion Sort) 구현  (0) 2021.09.18
선택정렬(Selection Sort) 구현  (0) 2021.09.15
버블정렬(Bubble Sort) 구현  (0) 2021.09.14
반응형

 

 

 

 

 

1. 필레이트(Fillrate)

- 그래픽 카드가 초당 화면에 렌더링할 수 있는 픽셀의 수를 의미한다. (픽셀 처리에 대한 부담)

- 렌더링 해야하는 픽셀의 수가 많거나, 프래그먼트 쉐이더가 무거우면 래스터라이저 스테이지에서 병목이 발생하는데 이것을 필레이트 병목이라고 한다.

- 필레이트 = 픽셀 수 X 프래그먼트 쉐이더 복잡도 X 오버드로우

 

 

 

2. 확인 방법

- 해상도를 변경해서 프레임을 확인해보면 된다. (해상도를 줄이면 렌더링 해야할 픽셀 수가 줄어들기 때문)

 

 

 

3. 해상도를 줄이는 방법

3-1) 코드로 변경하기

- Screen.SetResolution() 메서드를 사용하여 해상도를 변경할 수 있다.

 

3-2) Project setting에서 변경하기(Android, iOS 한정)

- EditProject SettingsPlayer에서 Resolution and PresentationResolution Scaling에서 설정이 가능하다.

- Resolution Scaling Mode가 기본값(Disabled)으로 되어있는데 Fixed DPI로 변경하고 Target DPI 값을 설정해주면 된다.

- Target DPI : 1인치에 몇개의 화소가 들어가는가(수치가 낮을수록 해상도가 낮아짐)

 

 

 

 

※ 하지만 해상도를 줄이면 유저가 알아차리기 쉽기 때문에 업스케일 샘플링을 사용하는데 이 부분은 추후에 작성 예정.

 

 

 

 

 

반응형
반응형

 

 

 

 

보통 카메라 흔드는 기능에 대해 구글링을 해보면 Random.insideUnitCircle이나 Sphere로 카메라를 흔드는 코드를 많이 볼 수 있었다. 그런데 이런식으로 구성을하면 끊기면서 흔들리는(?) 느낌이 강하게 들어서 좀 더 찾아보니 관련된 에셋이 몇개 있었는데 받아서 뜯어보니 Mathf.PerlinNoise라는 노이즈 함수를 이용해서 카메라를 흔드는것을 봤다.

 

에셋에서는 위치 및 회전값까지 변경해서 건드리고있었는데, 회전값까지 변경하는 코드는 카메라 흔들림이 너무 정신없어서 전부 빼고 x, y 좌표만 변경하는 방법으로 코드를 바꿨다.

 

※ Perlin noise (펄린노이즈)

- 단계적 텍스처를 만들기 위해 개발된 노이즈 함수, 지형(마인크래프트 등)을 생성할 때 이용한다고한다.

- 위키 링크 (영어)

- 유니티 링크 (영어)

 

 

 

 

코드

using System.Collections;
using UnityEngine;

public class CamShake : MonoBehaviour
{
    [SerializeField]
    private float m_roughness;      //거칠기 정도
    [SerializeField]
    private float m_magnitude;      //움직임 범위

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Shake(1f));
        }
    }

    IEnumerator Shake(float duration)
    {
        float halfDuration = duration / 2;
        float elapsed = 0f;
        float tick = Random.Range(-10f, 10f);

        while (elapsed < duration)
        {
            elapsed += Time.deltaTime / halfDuration;

            tick += Time.deltaTime * m_roughness;
            transform.position = new Vector3(
                Mathf.PerlinNoise(tick, 0) - .5f,
                Mathf.PerlinNoise(0, tick) - .5f,
                0f) * m_magnitude * Mathf.PingPong(elapsed, halfDuration);

            yield return null;
        }
    }
}

※ roughness : 거칠기 정도, 카메라가 움직이는 동안 카메라의 떨림을 제어하는 수치이다. 값이 높아질수록 카메라가 움직이는 시간동안 많이 떨린다.

※ magnitude : 카메라 움직임 범위, 카메라가 움직이는 범위 수치이다.

※ tick : 펄린노이즈 함수에 들어갈 값이다. 초반에 랜덤으로 값을 설정하는 이유는 노이즈 함수에 들어가는 값을 다르게하기 위해서이다. (항상 같은 움직임으로 흔들게 하고싶으면 틱값을 랜덤이 아닌 고정값으로 초기화하면 된다.)

 

 

 

 

결과

 

 

 

 

 

 

 

반응형
반응형

 

 

 

 

유니티 에셋스토어에서 받은 모델에 베지어 커브로 움직이는 스크립트가 있었는데, 해당 스크립트를 Record기능으로 녹화를 하면 다음과 같은 에러가 발생했다.

 

- Invalid AABB

- Assertion failed on expression: 'IsFinite(distanceForSort)'

- Assertion failed on expression: 'IsFinite(distanceAlongView)'

 

구글링을 해봤는데 어떤 글에서는 모델의 문제라고 하고, 어떤 글에서는 Physics 설정문제라는 글이 보였는데..

나같은 경우엔 0으로 나눗셈을 하는데서 발생하는 에러였다.

 

베지어 커브 스크립트에 변수를 Time.deltaTime으로 나누는 코드가 있었는데, Time.deltaTime을 Record로 녹화를 시작하면 값이 0이되는것같다.

그래서 Time.deltaTime을 고정값으로 따로 수정하니 해당 에러가 발생하지 않고 정상적으로 작동했다.

 

 

 

 

반응형
반응형

 

 

 

 

유니티에서는 색공간 옵션에 Gamma와 Linear가 존재한다.

Linear의 경우 사실적인 색이 표현되고, Gamma의 경우 사람의 눈에 자연스럽게 느껴지는 색으로 표현이된다.

 

위 그라데이션 이미지는 사람이 보기에 Gamma가 더 자연스러워 보이지만 Linear에서 표현된 색이 진짜 그라데이션 색상이다. 하지만 사람이 볼때 Linear 그라데이션이 어색해보이는데 해당 현상은 베버의 법칙으로 설명할 수 있다.

 

베버의 법칙은 간단하게 설명하면, 자극이 없던곳에 추가된 자극은 민감하게 느끼고(Linear의 검은부분에서 흰색으로 넘어가는 부분) 이미 자극을 받은 상태에서는 자극이 추가(Linear의 회색에서 흰색으로 넘어가는부분)되도 민감하게 느껴지지 않는다는 말이다.

그렇기 때문에 Linear그라데이션에서는 진짜 색인데도 불구하고 사람이 볼때에는 어색해보인다.

 

그렇기 때문에 기존 Linear 색에서 출력을 더 떨어뜨려서 사람이 인지할때 자연스럽게 보이게하는게 Gamma 보정이다.

이렇게 모니터에 출력될 때 Gamma 보정이 들어가기 때문에 기존의 Linear 이미지를 저장할 때 기존 이미지의 색상보다 더 밝게하여 저장한다.(sRGB라 한다.)

 

이걸로 Linear와 Gamma의 차이를 알아보았고, 파이프라인에서의 차이점을 알아보자.

만약 Add 이펙트를 사용한다고 가정했을때 각 파이프라인에서의 처리는 다음과 같다.

 

 

 

Gamma 파이프라인

  • Gamma 파이프라인에서는 sRGB상태에서 Add를 하게된다. 그렇게되면  겹치는 부분에서 너무 밝아져서 해당 부분의 색상 데이터가 날아가버리게된다.
  • 이런 상태에서 Gamma 보정이 들어가면 결과적으로 하얗게 뜨게되어 어색하게보인다.

※ 위 그림에서 Linear는 파이프라인을 뜻하는게 아니라, 원본 이미지라고 생각하면 된다.

 

 

 

Linear 파이프라인

  • Gamma 파이프라인과 다르게 sRBG 영역에서 더하지 않고 Add 연산을 하기전에 엔진에서 어둡게 샘플링을 한다음 Add처리를 한다. (Linear를 지원하는 하드웨어에서는 샘플링시에 코스트가 들어가지 않는다.)
  • 해당 결과를 sRBG로 밝게해서 저장한 뒤 디스플레이로 출력하게되기 때문에 Gamma 파이프라인과 다르게 자연스럽게 출력되는 것을 확인할 수 있다.

 

 

결과적으로 Add 연산을 밝게한 상태에서 연산을 하느냐 어둡게한 상태에서 연산을하느냐의 차이가 Gamma와 Linear의 차이점이다.

그래서 URP나 HDRP의 경우 컬러 스페이스의 기본설정이 Linear로 되어있고 레거시의 경우 Gamma로 되어있다.

 

왜 레거시 파이프라인에서 Gamma가 기본설정이냐면, 구형 하드웨어에서는 Linear를 지원하지 않기때문인데 Linear를 지원하는 디바이스 조건은 다음과 같다.

 

 

 

Android

  • Graphics API : OpenGL 3.0 이상
  • Minimum API Level  : 4.3(API Level 18) 이상

 

 

iOS

  • Graphics API : Metal
  • iOS Version : 8 이상

 

 

외국의 경우 구형 디바이스를 사용하는 곳도 있기 때문에, 구형 디바이스도 서비스 대상에 포함되어있으면 어쩔 수 없이 Gamma 파이프라인밖에 선택지가 없지만 그렇지 않으면 Linear 파이프라인으로 사용하는것이 좋다.

※ Gamma로 작업하다가 Linear로 바꾸는것이 아닌 프로젝트 초반부터 Linear로 시작해야 번거로움을 덜수있다.

 

 

 

※ 이해가 가지 않으면 다음 영상 참고

 

 

 

 

 

 

 

반응형

+ Recent posts