렌더링 기초는 앞 셰이더 포스팅에도 했지만 렌더링 파이프라인은 중요하기 때문에 한번 더 집고 넘어가겠습니다.

유니티 셰이더 파이프라인을 간단하게 보고 자세한건 따로 포스티하겠습니다.

대략적으론 3D 물체를 2D 화면까지 표현하는 과정인데

https://youtu.be/KnueAgpUL3Y

설명보단 영상이 좋을꺼 같아 준비했습니다. 이 포스팅은 위 영상을 토대로 갑니다.

설명은 1분부터 5분까지입니다.

이제 유니티에서 프로젝트를 생성해보겠습니다. 생성 전에 버전은 2019.3 버전 이상을 사용해야합니다.19.4버전을 사용하겠습니다. 템플릿은 Universal RP(Render Pipeline)을 클릭하고 생성합니다.

아래 파일을 삭제해줍니다.

Edit -> Project Settings -> Graphics를 보면 UniversalRP-HighQuality가 들어가있습니다. 클릭 시 Assets > Settings 파일에 있습니다. 여러 파일이 있습니다. 사양에 따른 설정 값 같습니다. 유니티에선 셰이더를 그래프 형식으로 보여주는 기능이 있습니다. 위는 원래 쓰던 코드형식

그리고 기존 프로젝트에서 렌더링파이프 프로젝트로 업그레이드 하는 방법입니다.

패키지 매니저를 열어 RP를 검색 후 Universal RP를 다운 받아줍니다. 화면에 RP가 여러종류가 있습니다. Light는 예전에 사용하던것, HD(High Definition)는 고성능 입니다. 정확히는 Universal RP의 노드를 몇가지 추가한 업그레이드 버전이라서 Universal RP의 노드를 다 알아야합니다.

설치를 다한 후 Edit -> Project Settings -> Graphics으로 가서 보면 None입니다. Create -> Randring -> Universal Rander Pipeline - Pipline Asset을 생성해줍니다. 그럼 두가지가 생성됩니다. 그중 짧은 Asset 파일을 끌어다가 None에 넣어줍니다.

기존 셰이더는 핑크색이 뜰텐데 Edit -> Universal Rander Pipeline -> Upgrade Project Materials to UniversalRP Materials(첫번째)를 클릭해줍니다. 이렇게 되면 기존 프로젝트도 업그레이드가 완료되었습니다.

이제 구를 생성하고 테스트를 해보면 머테리얼 셰이더의 기본값이 바낀걸 볼 수 있습니다.

아래 처럼 PBR(Physically Based Rendering) Graph 물리기반렌더링으로 머테리얼을 제작 가능하고 위에 2D Renderer를 열어보면 2가지가 있는데 위에껀 빛에 반응 밑에껀 빛에 반응하지 않는 셰이더를 생성하는겁니다.

2D에서 나와서 Unlit 빛에 반응하지 않고 PBR는 물리기반 현실 세계 VFX 파티클을 많이 만드는 시스템에서 사용 Sub 는 그래프를 묶을 수 있습니다. 이제 PBR Shader를 만들어보겠습니다.

만들면 아래와 같이 되는데 PBR Shader 오른 클릭 후 머테리얼을 생성하면 머테리얼을 직접 그래프 드래그 드롭 안해도 들어가있는 상태입니다. 그리고 이 머테리얼을 구에 넣어줍니다.

이제 만들어둔 PBR Shader을 더블 클릭하면 그래프가 뜹니다.

요기까지 기본 세팅하고 그래프를 여는걸 해봤습니다. 알고리즘 공부 후 이어서 해보겠습니다. 

Shadertoy 튜토리얼 한글번역

셰이더 토이 WebGL 기반, OpenGL 베이스로된 사이트입니다. 튜토리얼을 진행해보겠습니다.

빈화면

"main" 함수는 쉐이더 효과를 출력하기 위해서 매초 마다 수십회 호출합니다. 컴퓨터 시스템은 초당 60프레임(60FPS)를 출력하려고 노력합니다. 하지만 GLSL 스크립트가 계산이 빡세지면 이 숫자는 더 낮아질 수 있습니다.

(FPS는 화면 아래쪽 정보바에 표시됩니다.)

균일 색상

frageColor는 쉐이더의 출력입니다. 이 값은 화면에 보여지는 이미지를 결정합니다.이 쉐이더는 이 값을 노란색으로 지정합니다. vec4( r, g ,b , a); 값입니다. 뒤에 값에 넣는거에 따른 색이 바낍니다.

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = vec4(1.0, 1.0, 0.0 ,1.0);
}

GLSL 벡터들

"fragColor" 는 vec4 객체에 할당되어야 합니다. 0~1 사이 실수 값이 담긴 4개 짜리 배열 입니다. 앞에 3 개의 숫자는 색상을 지정 하고 4번째 숫자는 불투명도(opactiy) 를 지정 합니다. (당장은 4 번째 투명도 값은 아무런 효과도 없습니다.)

하나의 vec2 객체는 4개의 float 을 인자로 받아 생성되거나 아래처럼, vec3 와 float. 2개의 인자를 생성자 인자로 받아 생성됩니다.

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	// Here we are seperating the color and transparency parts
	// of the vec4 that represents the pixels.
	vec3 color = vec3(0.0, 1.0, 1.0);
	float alpha = 1.0;
	
	vec4 pixel = vec4(color, alpha);
	fragColor = pixel;
}

현재 셰이더 토이보단 유니티 셰이더쪽을 익히는게 좋을꺼같아서 유니티 셰이더를 앞으로 연재하겠습니다.

이제부터 렌더링 파이프라인 (Rendering Pipeline) 설명입니다.

DirectX 그래픽스 파이프라인 순서 및 기본 설명과 기본 지식 블로그의 자료로 정리했습니다.

그래픽스 파이프라인(Graphics Pipeline) 과정

랜더링 파이프라인 (Rendering Pipeline) 과정

 

 

그래픽스 파이프 라인과 랜더링 파이프 라인을 합쳐놓은 그림

바로 위 그림 출처 : [3D] 그래픽스 파이프 라인 (tistory.com)

그림은 완벽히 이해 후 다시 만들어서 수정할 예정

알아 보던 중 헷갈리게 두개의 그래프가 나왔습니다. 차이는 그래픽스 파이프라인은 렌더링 파이프라인 속에 포함 되어있으며 같다라고도 볼 수 있습니다.

유니티 파이프라인 간략 설명(reto0) 2/3

유니티 파이프라인 간략 설명(reto0) 3/3

 

자세한 설명 

1. 3D 모델 구축 ( 로컬 스페이스 )

- 3D 모델을 만들어서 '로컬 좌표계'에 띄우는 단계를 말한다 (CPU 담당)

그래픽스 파이프라인 3D 모델구축 (로컬 스페이스) 자료

 

2. 가상 공간의 배치 ( 월드 스페이스 )

- 구축한 모델을 월드 좌표계롤 욺겨 하나의 장면을 구성하는 것(CPU 담당)

 

후에 자세한 설명은 포폴 마무리 후 좀 더 알아보겠습니다.

화면에 색을 칠하는(Shading) 프로그램

동작방식 : 렌더링 파이프라인의 일부를 유연하게 변경하는 프로그램

렌더링 파이프라인의 일부 중 프로그래머가 수정하게 열어주었고 그걸 셰이더라고 부른다.

셰이더가 없을 땐 버텍스 3개를 받아서 삼각형을 만들면 다 똑같은 삼각형이였지만 셰이더로 인해 여러가지 결과가 출력이 가능하게 된것이다.

유니티는 서피스 셰이더, 버텍스/프래그먼트 셰이더, 고정함수 셰이더 총 3가지의 셰이더를 지원합니다.]

주로 사용하는건 서피스, 버텍스/프래그먼트이며 

버텍스 셰이더는 정점의 정보값을 변화시켜서, 물체를 특별한 위치로 옮기거나, 텍스처를 바꾸거나, 색상을 바꾸는 등의 일을 할 수 있다. 하지만 기존의 정점을 지우거나 새로운 정점을 추가하는 등의 작업은 할 수 없다.

프래그먼트 셰이더는 최종 출력될 색을 채워 넣는 일을 한다. (이미 밑그림이 완성된 종이를 받아서 그위에 색을 칠하는 일)

그리고 셰이더는 한번에 그리는게 아닌 한번에 여러개를 실행하는 형식으로 만들어진다.

예로 3개의 버텍스를 받아서 삼각형을 그릴 시 1개 버텍스씩 찍고 한번에 3개를 실행한다.(여러가지를 한번에)

 

렌더링 파이프를 이제 뜯어볼 생각입니다. 렌더링 파이프가 실행 되기 전에 그래픽스 API 초기화 한번 실행해야합니다.

과정은 GPU 디바이스 생성 <-> 커맨드 큐 생성 - 렌더링 파이프라인 상태 생성

GPU 디바이스 생성 - 현재 기기의 GPU를 표현하는 오브젝트 한번만 생성, 하나만 존재

커맨드 큐로 부터 커맨드를 받아들여 실행

 

커맨드 큐 - GPU에게 전달할 명령을 쌓아두는 곳, 한번만 생성, 하나만 존재, GPU 디바이스로 이어짐

CPU와 GPU의 속도를 맞춰 자원 낭비를 막기 위해 CPU에서 명령을 내린걸 커맨드 큐에서 명령을 예약하고 하드웨어 언어로 번역하여 커맨드 버퍼에 쌓고 성능에 맞춰 GPU가 빼가는것 (즉시 실행되는게 아님)

렌더링 파이프라인 상태 생성 - 렌더링 파이프라인의 상태를 표현, 렌더링 파이프라인에 사용할 속성들을 가짐, 여러개 생성 가능

상태를 표기한걸 렌더링 파이프라인 서술자라고 표기하며 렌더링 파이프라인이 어떤식으로 동작할 지 묘사하는 오브젝트이다. 그중 정점 서술자는 정점의 구성을 묘사하며 정점을 조립할 때 사용

위 작업이 끝나면 마지막으로 사용할 데이터 로드 (모델, 텍스쳐등) RAM에서 그래픽카드로 전송할 데이터를 RAM에 올려 놓는다. 삼각형을 보낼 시 3개의 정점에 대한 데이터를 가지고 있고 이걸 메모리에 올릴 것이다. 물론 게임 엔진이 알아서 올려준다. 하지만 주의 해야할 사항은 요기서 정점은 위치만을 가르치는게 아니고 위치는 정점의 속성 중 하나 일뿐입니다.

요기까지가 렌더링 파이프라인전 실행되는 그래픽스 API 초기화 과정이였습니다.  물론 유니티에선 다룰 일은 없습니다. 하지만 이해하고 가면 좋을것 같아서 공부하였습니다.

드로우 콜은 GPU가 처리하기 전 단계인 드로우 콜은 최적화에 있어서 중요한 단계라고 합니다. 여러 방법이 있지만 나중에 공부하여 다뤄보도록 하겠습니다. 일단 역할은 오브젝트를 한번 그리는데 필요한 명령들의 묶음입니다. 이건 따로 게시글로 다뤄볼 예정이니 대략적인 개념만 잡고 가겠습니다. 이렇게 GPU로 넘어가면 될것 같습니다.

주변의 모든 방향에서 캡처하는 카메라와 유사합니다. 캡처된 이미지는 반사 머티리얼이 있는 오브젝트에서 사용할 수 있는 큐브맵(Cubemap)으로 저장됩니다. 특정 씬에는 여러 반사 프로브를 사용할 수 있고, 가장 가까운 프로브가 생성한 큐브맵을 사용하도록 오브젝트를 설정할 수 있습니다. 이렇게 하면 오브젝트의 반사가 주변 환경에 따라 매우 사실적으로 변할 수 있습니다.

Reflection Probe

Reflection Probe 컴포넌트를 씬의 아무 오브젝트에나 추가할 수 있지만, 각 프로브를 별도의 빈 게임 오브젝트에 추가하는 방법이 일반적입니다. 일반적인 워크플로는 다음과 같습니다.

  • 새로운 빈 게임 오브젝트를 생성(메뉴: GameObject > Create Empty)하고, 그런 다음 Reflection Probe 컴포넌트를 오브젝트에 추가(메뉴: Component > Rendering > Reflection Probe)합니다. 또는 씬에 프로브가 이미 있는 경우 이 씬을 대신 복제(메뉴: Edit > Duplicate(Ctrl+D)하면 더 쉽습니다.
  • 새로운 프로브를 원하는 위치에 놓고 프로브의 Offset 점과 그 효과 영역의 크기를 설정합니다.
  • 필요하다면 프로브에 다른 프로퍼티를 설정하여 동작을 커스터마이즈합니다.
  • 필요한 위치가 모두 할당될 때까지 프로브를 계속 추가합니다.

반사를 보려면 씬에 반사 오브젝트가 하나 이상 있어야 합니다. 간단한 테스트 오브젝트를 다음과 같이 생성할 수 있습니다.

  • 구체(메뉴: GameObject > 3D Object > Sphere)와 같은 프리미티브 오브젝트를 씬에 추가합니다.
  • 새 머티리얼을 생성(메뉴: Assets > Create > Material)하고 기본 Standard 셰이더를 제자리에 놔둡니다.
  • Metallic 및 Smoothness 프로퍼티를 모두 1.0 으로 설정하여 머티리얼을 반사 머티리얼로 만듭니다.
  • 새로 만든 머티리얼을 구체 오브젝트로 드래그하여 할당합니다.

추가 설정으로 Lighting에서 Auto Generate을 꺼주고 직접 컨트롤 합니다. 

반사할 물건은 Static 옵션에서 Reflection Probe Static으로 설정해줍니다.박스 사이즈는 맵의 크기만큼 맞춰주면 됩니다. 박스 사이즈 밖으로 물체가 나갈 시 반사를 안하게 됩니다.움직이는 물체일 시 Type에 Realtime과 Every frame 설정을 해줘야합니다.

이제 구체에는 프로브로부터 얻은 반사 효과가 표시됩니다.

스탠다드 셰이더(Standard Shader)

포괄적인 기능을 가진 기본 셰이더, 암석, 나무, 유리, 플라스틱, 금속과 같은 현실 오브젝트를 렌더링하는 데 사용할 수 있으며, 다양한 셰이더 타입과 조합을 지원합니다.

물리 기반 셰이딩(PBS) 이라는 고급 광원 모델을 포함합니다. 물리 기반 셰이딩은 현실과 유사하게 머티리얼과 광원 간의 상호작용을 시뮬레이션합니다. 그리고 오브젝트가 받는 광원보다 더 많은 광원을 반사할 수 없다는 에너지 보존 법칙, 모든 표면은 지표각에서 반사율이 높아진다는 프레넬(Fresnel) 반사 법칙, 표면이 자신을 가린다는 지오메트리 텀 등을 포함한 물리 법칙을 따릅니다.

스탠다드 셰이더 조명 수학 구현은 Disney 모델을 디퓨즈 컴포넌트에 사용하고 GGX 모델을 스페큘러에 사용하며, Smith Joint GGX 가시성 조건과 Schlick Fresnel 근사값을 적용합니다.

  • 에너지 보존(Energy conservation) - 오브젝트가 받는 광원보다 더 많은 광원을 반사하지 않는다는 물리 기반 개념입니다. 머티리얼이 더 많이 반사할수록 산란은 덜 일어나야 하며, 표면이 부드러울수록 강조 지점은 작지만 강하게 강조되어야 합니다.

표면 위의 각 지점에 렌더링된 조명은 주변에서 받은 광원과 동일한 양이라고 간주되어 계산됩니다. 거친 표면의 미세 표면은 더 넓은 영역의 광원에 의해 영향을 받습니다. 포인트 A는 광원으로부터 빛을 받아 카메라로 반사합니다. 포인트 B는 하늘의 주변광에서 청색 색조를 받습니다. 포인트 C는 주변의 지면 컬러에서 주변광 및 반사광을 받습니다.

  • 고명암비(High Dynamic Range, HDR) - 일반적인 0–1 범위 밖의 컬러를 의미합니다. 예를 들어, 태양은 푸른 하늘보다 쉽게 10배 이상 밝을 수 있습니다. 자세한 설명은 Unity 매뉴얼의 HDR 페이지를 참조하십시오.

HDR을 사용한 씬입니다. 자동차 창문에 반사된 태양광은 HDR을 사용해 처리되었기 때문에 씬의 다른 오브젝트보다 휠씬 더 밝게 보입니다.

 

Graphics(그래픽스 유니티 매뉴얼)

Edit - Project Settings - Graphics에서 사용 가능한 셰이더 설정 기능이다.

Scriptable Render Pipeline Settings

Unity가 사용하는 기본 렌더링 파이프라인을 사용하는 대신 씬이 렌더링되는 방법을 제어할 수 있도록 커맨드 몇개를 정의합니다.

Transparency Sort Mode

특정 축상의 거리를 기준으로 오브젝트 렌더링 순서를 정의, Unity 렌더러는 레이어 수, 카메라에서 떨어진 거리등 다양한 기준으로 정렬됩니다. 일반적으로 높이를 기준으로 또는 Y축을 따라 스프라이트를 정렬할 때와 같은 2D 개발에서만 유용

Custom Axis 기능(값에 따라서 오브젝트를 정렬)

Tier Settings

미세 조정하여 플랫폼에 따른 렌더링과 셰이더 컴파일을 조정할 수 있다. 성능 개선에 쓰임 

티어 변수 정리 (GraphicsTier 유니티 매뉴얼)

관심있는건 정리해놓고

Standard Shader Quality - 스탠다드 셰이더의 품질을 설정

스탠다드가 무엇인지 궁금할 시 (스탠다드 셰이더)

Reflection Probes Box Projection, Reflection Probes Blending

반사 프로브에 대한 설정 (반사 프로브)

Detail Normal Map - 디테일 노멀 맵 활성화 (디테일 노멀 맵 유니티 매뉴얼)

Enable Light Probe Proxy Volume - 라이트 프로브의 3D 그리드 렌더링을 활성화합니다.

Use HDR - HDR 렌더링을 활성화합니다, 

HDR Mode - HDR 이 활성화되었을 때 HDR 버퍼에 사용할 포맷을 선택합니다.

기본값은 FP16 (나중에 알아보자)

ㄴ FP16 - 컬러 렌더 텍스처 포맷, 채널당 16비트 부동 소수점입니다.

ㄴR11G11B10 - 컬러 렌더 텍스처 포맷, R 및 G 채널은 11비트 부동 소수점이고, B 채널은 10비트 부동 소수점입니다.

Rendering Path (작성중)

Realtime Global Illumination CPU Usage - 런타임 시점에 최종 조명 계산에 할당할 CPU 사용량을 선택합니다. 값을 높이면 더 많은 CPU 스레드를 사용하여 조명 변화에 대한 시스템 반응 속도를 높입니다.
참고: 일부 플랫폼에서는 워커 스레드가 모든 CPU를 점유하도록 허용하며, 최대값을 실행하는 플랫폼도 있습니다. 예를 들어 Xbox One과 PS4는 최대 4개의 CPU 코어를 허용합니다. Android 기기에서는 bigLittle 아키텍처인 경우 적은 CPU만 사용됩니다. 그 외에는 최대값이 전체 CPU보다 하나 적은 값입니다.

Low 25%, Medium 50%, High 75%, Unlimited 100%

Built-in Shader Settings

Deferred - 디퍼드 셰이딩에 사용합니다.

Deferred Reflection - 디퍼드 라이팅을 따라 반사 프로브에 사용합니다.

Screen Space shadows - PC/콘솔 플랫폼에서 방향 광원에 대해 캐스케이디드 그림자 맵을 사용합니다.

Legacy deferred - 레거시 디퍼드 라이팅을 사용합니다.

Motion vectors - 오브젝트 기반 모션 벡터 계산을 위해 사용합니다.

Lens Flare - 렌즈 플레어에 사용합니다.

Light Halo - 광원 헤일로에 사용합니다.

No Support - 비활성화

Built-in Shader - 기본 옵션, 셰이더를 계산에 사용

Custom Shader - 호환 가능 셰이더를 계산에 사용, 디퍼드 렌더링을 자세히 커스터마이징 할 수 있도록 해줍니다.

+ Recent posts