Ssssong += Dev

[유니티/DirectX/OpenGL] 셰이더 본문

개발/공부

[유니티/DirectX/OpenGL] 셰이더

ssong_dev 2022. 10. 26. 17:15

0. Materials / Shaders / Textures

https://docs.unity3d.com/kr/530/Manual/Shaders.html

 

머티리얼, 셰이더 및 텍스처(Materials, Shaders & Textures) - Unity 매뉴얼

Unity에서 렌더링은 Materials, Shaders 및 Textures를 사용하여 수행됩니다.

docs.unity3d.com

Materials : 사용되는 텍스처에 대한 레퍼런스, 타일링 정보, 컬러 틴트 등을 포함한 표면 렌더링 방법의 정의

사용 가능 옵션은 머리티얼에 사용하는 셰이더에 따라 달라진다.

 

Shaders : 조명 입력과 머티리얼 설정에 따라 렌더링된 각 픽셀의 컬러를 계산하는 수학적 계산식 및 알고리즘이 포함된 스크립트

 

Textures : 비트맵 이미지. 

 

 

 

 

 

1. HLSL과 GLSL

 

 

HLSL(Hight - Level Shader Language) : DirectX에서 프로그래밍 가능한 셰이더와 함께 사용하는 C와 유사한 상위 수준 셰이더 언어이다.

고수준의 언어이기에 가독성이 좋고 관리에 이점이 있다. 

 

GLSL : OpenGL의 표준 셰이딩 언어이며 개발자가 그래픽스 파이프라인을 직접 제어할 수 있는 언어이다.

매킨토시, 윈도, 리눅스 등 여러 운영체제 간의 호환성을 지원한다.

 

GLSL에서 Shader의 진입 함수로 main() 함수가 사용되나 HLSL은 그 함수 이름이 main으로 고정되지 않고 직접 정의 가능하다.

GLSL에서는 Vertex Shader와 Pixel Shader에 각각 main 함수가 있어야 하기에 두 파일을 따로 컴파일하여야 하지만

HLSL에서는 진입호출 함수를 직접 정할 수 있으므로 하나의 파일로 관리가 가능하다.

 

 

HLSL에서는 GLSL과 달리 Semantics가 있어야 한다. 시멘틱은 해당 변수의 성격을 정해준다.

 

[출처]

https://gpututorial.blogspot.com/2018/01/semantics-in-hlsl.html

 

Semantics in HLSL

Semantics in HLSL Direct3D 의 Shader에서는 CPU가 전달한 메모리, 쉐이더 코드, GPU 렌더링 파이프라인간 연계를 위하여 시멘틱 semantic 을 사용한다. 무슨말이냐 하면… 가령 버텍스 쉐이더와 프레...

gpututorial.blogspot.com

이 글에 나와있는 것과 같이 Semantic은 변수들이 어떤 자료와 연결될 지 알려주는 것이다.

대표적으로 SV_Position(레스터라이즈 이전 셰이더에서 출력)과 SV_Target(버텍스 셰이더에서 출력)이 있다. 

 

픽셀셰이더의 경우 출력으로 SV_Delth와 SV_Target만 사용할 수 있다.

 

DirectX HLSL에서의 시멘틱 의미 문서

https://learn.microsoft.com/ko-kr/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics?redirectedfrom=MSDN 

 

의미 체계 - Win32 apps

의미 체계는 의도한 매개 변수 사용에 대한 정보를 전달하는 셰이더 입력 또는 출력에 연결된 문자열입니다.

learn.microsoft.com

 

 

 

2. Rendering Pipeline

 

[출처]

https://parodev.tistory.com/30

 

그래픽스 파이프라인이란? (Graphics Pipeline)

그래픽스 파이프라인이란?  3D 컴퓨터 그래픽스에서 그래픽스 파이프라인(Graphics Pipeline) 이란 3차원의 도형 혹은 이미지를 2차원 래스터 이미지로 표현을 하기 위한 단계적 방법(방법을 몇 단계

parodev.tistory.com

3D 컴퓨터 그래픽스에서 그래픽스 파이프라인(렌더링 파이프라인)이란 3차원 도형 혹은 이미지를 래스터 이미지로 표현하기 위한 단계적 방법을 의미한다. 

 

 

 

 

 

3. Vertex Shader와 Fragment Shader

 

vertex buffer data는 vertex 정보를 가지고 있는 메모리 블럭이다. 위치, 색상, 텍스처 등의 정보를 가지고 있다.

Vertex Shader는 이런 vertex data를 받아 각 점을 생성한다. 

Fragment Shader는 레스터라이제이션을 통해 생성된 fragment를 처리한다. 

 

*Fragment Shader를 Pixel Shader라는 용어로 혼용해서 사용하기도 하긴 하는데

검색해보니 fragment로 생성된 상태에서 동작하지 '아직' pixel 상태가 아니기 때문에 Fragment Shader라는 말이 더 적합해 보인다.  

 

-> 집에 있는 DirectX 책 좀 찾아봐야겠는걸...

 

[출처]

https://gpututorial.blogspot.com/2018/01/vertex-shader-and-pixel-shader-glsl.html

 

Vertex Shader and Pixel Shader (GLSL)

Vertex Shader and Pixel Shader (GLSL) Shader에 대하여 인터넷을 검색해 보면 많은 자료가 나온다. 이러한 자료들은 대부분 비슷한 내용들을 담고 있다. Shader의 의미나 그 코딩 방법에 대하여 설명이...

gpututorial.blogspot.com

 

* GLSL에서 uniform / attribute / varying

- uniform은 전역 변수와 같은 역할. vertex shader와 fragment shader에서 모두 공유할 수 있지만 값을 읽는 것만 가능하다.

- attribute는 vertex shader에서만 사용 가능하다.

- varying은 vertex shader에서 fragment shader로 값을 전달하는 경우에 사용한다.

 

 

 

 

 

4. SubShaderLab

 

유니티 공식메뉴얼 ShaderLab 구문 사용법

https://docs.unity3d.com/kr/530/Manual/SL-Shader.html

 

ShaderLab 구문 - Unity 매뉴얼

Unity의 모든 셰이더 파일은 “ShaderLab”이라는 선언형 언어로 작성되어 있습니다. 이 파일에서 중첩 중괄호 구문은 셰이더를 서술하는 다양한 요소를 선언합니다. 예를 들어, 어떤 셰이더 프로퍼

docs.unity3d.com

 

https://jinhomang.tistory.com/43

 

유니티 셰이더의 기초 #1

안녕하세요, 흑기사입니다. 다들 유니티로 게임 만드시느라 밤낮없이 매우 바쁘실텐데요.. 너무 바쁜 나머지, 아직 유니티 셰이더 쪽은 살펴보지 못하신 분들께 조금이나마 도움이 되었으면 하

jinhomang.tistory.com

유니티에서 사용하는 셰이더 스크립트 언어이다. 유니티는 멀티플랫폼 엔진이기 때문에 다양한 플랫폼과 디바이스에 대응해야 하고, 따라서 공통의 인터페이스가 요구되므로 이러한 언어를 사용한다.

 

유니티 셰이더 파일은 하나의 Shader 블럭이 있고 그 안에 여러 SubShader가 있는 형태로 구성된다. 

여러 SubShader를 통한 구현을 할 수 있게 구성된 이유는 그래픽 하드웨어의 다양성 때문이다. 어떤 셰이더가 특정 하드웨어에서 지원되지 않아 동작하지 않는 현상을 막는다. 

 

Fallback은 모든 SubShader들이 동작하지 않는 경우 지정된 이름의 셰이더를 찾아 적용해준다.

 

Pass는 셰이더에서 렌더링 단위를 의미한다. 따라서 SubShader 안의 Pass 수 만큼 오브젝트가 렌더링된다.

 

 

 

URP에서 사용하는 Pass tags는 유니티 문서를 참고하면 된다.

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@10.1/manual/urp-shaders/urp-shaderlab-pass-tags.html

 

URP ShaderLab Pass tags | Universal RP | 10.1.0

This section contains descriptions of URP-specific ShaderLab Pass tags. The value of this tag lets the pipeline determine which Pass to use when executing different parts of the Render Pipeline. If you do not set the LightMode tag in a Pass, URP uses the S

docs.unity3d.com

 

 

 

 

 

5. Rendering path

 

https://docs.unity3d.com/kr/530/Manual/RenderTech-DeferredShading.html

 

디퍼드 셰이딩 렌더링 경로 - Unity 매뉴얼

이 페이지에서는 디퍼드 셰이딩 렌더링 경로에 대해 자세하게 설명합니다. 기술에 대한 대략적인 설명은 위키피디아: 디퍼드 셰이딩을 참조하십시오.

docs.unity3d.com

https://learn.unity.com/tutorial/understanding-rendering-paths-2019-3?signup=true# 

 

Understanding Rendering Paths - Unity Learn

Realtime lights can be expensive to performance due the calculations that have to be done to determine the valid pixel color when there is a light in range. So, when you have a scene with varying amounts of light that need to be rendered, there are two ren

learn.unity.com

https://learnopengl.com/Advanced-Lighting/Deferred-Shading

Deferred Rendering

- 자연 빛! 가장 높은 빛과 그림자 충실도를 가졌다. 실시간 빛이 많을 때 사용하면 좋다. 

- 첫 패스에 전부 계산해서 렌더한다. 

- 광원의 수보다 광원의 영향을 받는 픽셀 기준으로 렌더 코스트가 생긴다.

- 높은 하드웨어 사양이 요구된다. 

- Orthographic(직교 투영)에서는 디퍼드 렌더링을 지원하지 않는다.

 

 

Forward Rendering

- 각 오브젝트에 영향을 미치는 가장 밝은 광원이 픽셀당 릿 모드에서 완전히 렌더링되고 다음 광원이 최대 4개까지 버텍스 당 릿 모드로 렌더링된다. 마지막으로 나머지 광원이 스피리컬 하모닉스(SH)로 렌더링된다. 

- 셰이더에 기반을 둔 렌더링이다.

- 광원의 수에 따라 오브젝트가 여러번 렌더링 될 수 있다. 따라서 광원이 많으면 렌더 시간이 늘어난다.

- 렌더링 속도가 빠르다.

 

 

 

 

6. LightMode 태그

https://docs.unity3d.com/kr/530/Manual/SL-PassTags.html

 

ShaderLab: 패스 태그 - Unity 매뉴얼

패스는 태그를 사용해 예상되는 렌더 방법 및 시기를 렌더링 엔진에 알립니다.

docs.unity3d.com

조명 파이프라인에서 패스가 담당하는 역할을 정의한다.

 

 

 

셰이더 연산 순서 

출처 : 유니티 도큐먼트

 

 

 

 

 

7. 셰이더 배리언트

 

공통 코드를 공유하는 셰이더에서 특정 키워드의 활성화 여부에 따라 다른 기능을 갖게 할 수 있다.

활성/비활성화된 키워드의 다양한 조합에 대해 생성된 별도의 셰이더 프로그램을 셰이더 배리언트라고 한다.

 

https://docs.unity.cn/kr/2020.3/Manual/SL-MultipleProgramVariants.html

 

셰이더 배리언트 및 키워드 - Unity 매뉴얼

공통 코드를 공유하는 셰이더 스니핏을 작성할 수 있지만, 특정 키워드가 활성화되거나 비활성화되면 다른 기능을 갖습니다. Unity가 이러한 셰이더 스니핏을 컴파일하면 활성화되거나 비활성화

docs.unity.cn

 

#pragma는 컴파일에게 그 뒤에 오는 내용에 따라 어떤 일을 하라는 전처리 명령이다.

 

[출처]

https://chulin28ho.tistory.com/591

 

shader_feature와 multi_compile의 차이

shader_feature와 multi_compile의 차이 #pragma shader_feature는 #pragma multi_compile과 매우 유사하고 shader_feature 셰이더의 사용되지 않는 배리언트가 게임 빌드에 포함되지 않는다는 유일한 차이점이 있..

chulin28ho.tistory.com

 

#pragma shader_feature

#pragma multi_compile

 

shader_feature 셰이더의 사용되지 않는 배리언트가 게임 빌드에 포함되지 않는다.

- 머티리얼에 설정되는 키워드에 가장 적합 (Emmision 연산을 할 것인지, 해당 머테리얼에서 노말맵을 쓸 것인지 등등)

- runtime에 변경되지 않는 경우! 

 

multi_compile

- 코드에서 전역으로 설정되는 키워드에 적합(라이트가 있는지, 섀도우가 있는지 등등)

- runtime에 enable, disable로 변경할 수 있는 경우 빌드에 포함시켜야 하므로 설정하는 키워드

 

#pragma shader_feature_local

#pragma multi_compile_local

 

로컬 지시문은 정의된 키워드를 전체 프로젝트에 적용하는 대신 해당 셰이더에 보관한다.

전역 API를 통해 특정 키워드 활성화하려는 경우를 제외하고는 로컬 키워드 쓰는 게 성능상으로 이득이다.

 

- 한계

  • 전역 키워드를 변경하는 API가 포함된 로컬 키워드(예: Shader.EnableKeyword 또는 CommandBuffer.EnableShaderKeyword)는 사용할 수 없습니다.
  • 셰이더당 최대 64개의 고유 로컬 키워드를 사용할 수 있습니다.
  • 머티리얼에 활성화된 로컬 키워드가 있고 해당 셰이더가 더 이상 선언되지 않는 셰이더로 변경되면 Unity는 새로운 전역 키워드를 생성합니다.

 

 

 

8. URP

 

-> 기존 Unity 빌트인 렌더 파이프라인을 사용하면 포워드 렌더링 경로와 디퍼드 렌더링 경로 중 하나를 택할 수 있었다.

하지만 커스텀 렌더링 전략은 추가할 수 없었고 기존 인젝션 포인트에서만 기존 전략을 확장할 수 있었다.

 

유니버설 렌더 파이프라인은 렌더러 개념을 도입함으로써 확장성이 향상되었다.

설정 시 파이프라인 에셋에 렌더러 목록을 선언하고 각 카메라에서 렌더러를 사용할 수 있다.

직접 렌더러를 만들고 파이프라인을 확장할 수 있다.

 

 

[출처]

https://blog.unity.com/kr/technology/how-the-lightweight-render-pipeline-is-evolving

 

URP - 경량 렌더 파이프라인의 진화 | Unity Blog

Unity 2019.3버전부터 경량 렌더 파이프라인(Lightweight Render Pipeline, LWRP)이 유니버설 렌더 파이프라인(Universal Render Pipeline, URP)으로 변경되었습니다. URP는 아름다운 그래픽과 뛰어난 성능을 제공하는

blog.unity.com

 

'개발 > 공부' 카테고리의 다른 글

[유니티] Gamma와 Linear  (0) 2022.11.02
[유니티/젠킨스] Jenkins  (0) 2022.10.28
[유니티] SerializedObejct  (0) 2022.10.06
[C#] C# Coding Conventions  (0) 2022.09.14
[C#] Flag연산  (0) 2022.09.14