Unity URP셰이더 개요 및 크로스 컴파일의 개념

Mati-as·2023년 8월 20일
0
post-thumbnail

텍스트### 크로스 컴파일러 (Cross Compiler)

크로스 컴파일러에 대한 설명을 찾아보면 Cross에 한영사전에 나오는 '교차'개념을 대입해서 오히려 더 혼동되게 설명하는 것 같습니다. 근데 여기서 Cross는 건너가는 이미지(혹은 cover)에 더 가깝습니다. 내가 있는 곳뿐 아니라, 다른 플랫폼까지 건너서 컴파일한다는 이미지에서 파생됐다는 느낌이 더 큽니다. X처럼 교차하는 이미지를 떠올리시면 안될 것 같습니다.

A cross compiler is a compiler capable of creating executable code for a platform other than the one on which the compiler is running. For example, a compiler that runs on a PC but generates code that runs on an Android smartphone is a cross compiler. -Wikipedia

즉, 자신의 플랫폼에서 돌아가는 컴파일러가, 안드로이드 등 스마트폰에서도 작동될 수 있도록 컴파일 코드를 생성하는 것을 말합니다.

더 일반적으로 말해서, 하나의 개발 호스트, 즉 컴파일러로 여러 플랫폼에 대응할 수 있도록 컴파일 코드를 생성할 수 있는 컴파일러를 크로스 컴파일러로 할 수 있습니다.

여러 기계에 컴파일을 하거나, 새로운 플랫폼에 부트스트래핑을 할 때 주로 사용됩니다.

URP Shader Overview

오늘 다룰 유니티 셰이더에서 관련 개념이 나오기에, 서론에 크로스 컴파일러 개념을 간단히 작성했습니다. URP 셰이더 중에서도 셰이더와 simple basic code를 다뤄보려고 합니다. 주석으로 전반적인 설명을 하고 이후에 조금 더 부연설명을 하겠습니다.

Basic simple basic code

//Shader의 start point. 셰이더 폴더와 이름을 여기서 결정합니다. 
Shader "URPTest/URPBaisc
{
	Properties
    {
// Properties Block이라고 부르며, 셰이더에 사용될 변수선언 및, Material Inspector에 노출시킵니다. 
    }
    SubShader
    {
 
    Tags
    {
//Render type과 Render Queue를 여기서 결정합니다.
    "RenderPipeline" = "UniversalPipeline"
    "RenderType" = "Opaque"
    "Queue" ="Geometry"
    }
    
//Pass는 그래픽 카드에서 실행되는 실제 셰이더 코드의 단계를 의미합니다.
    Pass
    {
//Pass 이름을 Universal Forward로 지정합니다. 
    Name "Universal Forward"
    
//Tags에서는 셰이더 동작방식을 정의하는 메타데이터를 포함합니다.*1) forward lighting mode는 URP에서 사요되는 라이팅 기법 중 한가지 입니다. 
    Tags {"LightMode" = "UniversalForward"}
    }
    
    HLSLPROGRAM 

    
/*
-hlslcc : HLSL cross compiler를 의미합니다. 
-GLES(OpenGL ES)에 대한 HLSLCC 컴파일러를 선호하도록 지시합니다. 
-#pragma로 컴파일러 지시사항을 제공합니다. 
*/
    #pragma prefer_hlslcc gles
    
    
// DirectX 11의 하위버전인 d3d11_9x를 제외합니다. 
    #pragma exclude_renderers d3d11_9x
    #pragma vertex vert
    #prgame frament frag
    
//URP 기본 조명함수를 포함시킵니다. 
//참고로 cg shader는 .cginc를, HLSL shader는 .hlsl을 include합니다. 
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"        	
    
//아래 코드에서는 셰이더의 핵심 부분을 나타냅니다.
    
//vertexbuffer에서 읽어올 정보를 선언 
    struct VertexInput
    {
    float4 vertex : Position;
    };
    
//보간기를 통해 버텍스 셰이더에서 픽셀 셰이더로 전달할 정보를 선언합니다.
    struct VertexOutput
    {
    float4 vertex  	: SV_POSITION;
    };

//버텍스 셰이더
    VertexOutput vert(VertexInput v)
    {
    VertexOutput o;
    o.vertex = TransformObjectToHClip(v.vertex.xyz);
    return o; 
    }
    
//픽셀 셰이더
    half4 frag(VertexOutput i): SV_Target
    {
    return half4(0.5, 0.5, 0.5, 1);
    }
    
    ENDHLSL
    }
  }
}
/*
참고) Forward 라이팅 모드는 URP에서 사용되는 라이팅 기법 중 하나입니다. 이 모드에서는 각 픽셀이나 버텍스에 대해 라이트가 직접 계산됩니다. 이 방식은 라이트의 수가 적을 때 효율적이며, 특히 투명 물체나 반사 물체에 적합합니다.
*/

간단하게 코드를 작성해 보았습니다. 하지만, DirectX나 여러 이론들이 배경지식이 기반되어야 하기에 주석을 조금 상세하게 달았습니다. 이외에도 일반적인 그래픽스이론이나, 셰이더의 전반적인 이해 등등 많은 것이 전제로 깔리기 때문에, 코드에서 어려운 부분은 계속해서 관련 자료를 학습해가며닫기학습 해가며 URP 코드 작성요령을 익히는 것이 좋을 것 같습니다. 오늘은 #pragma에 작성한 크로스컴파일 관련 이야기를 잠깐 하고 마무리하겠습니다.닫기마무리 하겠습니다.

pragma

C언어에서 pragma는 컴파일러가 입력을 처리하는 방법을 지정하는 문법입니다. 여기서는 셰이더가 어떻게 컴파일될지를 지시하는 전처리 문법입니다.

#pragma prefer_hlslcc gles

유니티에서는 여러 가지 셰이더 컴파일러 및, 크로스 컴파일러가 사용됩니다. 예를 들어 SRP경우 안드로이드를 위해 HLSLcc를 사용합니다. OpenGL ES 그래픽 API(Android)를 사용하는 플랫폼에서는 HLSLcc가 기본적으로 사용되지는 않기에 강제로 실행해 줄 필요가 있는 것입니다.

HLSLcc 부연설명

HLSLcc는 DIrectX 셰이더 바이트 코드 크로스 컴파일러입니다. GLSL(OpenGL 3.2 이상), GLSL ES(OpenGL ES 2.0 이상), GLSL for Vulkan Consumption(SPIR-V생성을 위한 GLSLang 인풋인 경우) ios를 위한 Metal 언어로 까지 변환을 해줍니다. 구체정보는
여기서 확인가능합니다.

#pragma exlude_renderers d3d11_9x

그리고 DirectX 9는 더이상 지원되지 않으니 제외합니다.

그 다음 Vertex Shader와 Pixel Shader를 정의하게 되는데, 이 다음 부터는 아래와 같이 렌더링 파이프라인등 다양한 개념이 등장하기에 다른 포스트에서 다뤄보도록 하겠습니다.

감사합니다.

출처: Unity Korea URP Training , Wikipeida.en

profile
plonker yet

0개의 댓글