[Unity] URP 셰이더 HLSL Pass와 Pass Commands

2023. 6. 12. 16:44Unity

728x90
반응형

Pass

Pass는 하나의 셰이더가 여러 번 그려야 하는 경우 사용된다.

Pass 아래에 Tags 명령어가 또 나오는데, SubShader의 Tags 명령어와 이름은 같지만 다른 목적을 가지고 있다. URP 렌더 파이프 라인에 의해 이 패스를 그릴지 말지를 결정하는 기준이 된다. Pass 안에 있는 명령어를 생략해도 디폴트 값으로 적용되며, SubShader에서 사용해도 된다. SubShader에서 Pass의 명령어를 사용하면 모든 Pass에 적용된다.

 

 

Shader "Universal Render Pipeline/Lit"
{
    Properties
    {
        // Specular vs Metallic workflow
        [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0

        [MainTexture] _BaseMap("Albedo", 2D) = "white" {}
        [MainColor] _BaseColor("Color", Color) = (1,1,1,1)

        _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5

        ...
    }

    SubShader
    {
        // Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
        // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
        // material work with both Universal Render Pipeline and Builtin Unity Pipeline
        Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
        LOD 300

        // ------------------------------------------------------------------
        //  Forward pass. Shades all light in a single pass. GI + emission + Fog
        Pass
        {
            // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
            // no LightMode tag are also rendered by Universal Render Pipeline
            Name "ForwardLit"
            Tags{"LightMode" = "UniversalForward"}

            ...
        }
        
        Pass
        {
            Name "ShadowCaster"
            Tags{"LightMode" = "ShadowCaster"}

            ...
        }
        
        Pass
        {
            // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
            // no LightMode tag are also rendered by Universal Render Pipeline
            Name "GBuffer"
            Tags{"LightMode" = "UniversalGBuffer"}

            ...
        }

URP에서 기본으로 제공하는 Lit의 셰이더이다. Pass 안에 Tags가 들어있는 것을 잘 보여준다.

URP에서는 셰이더에 패스를 아무리 많이 추가해도 렌더 파이프라인에서 허용한 패스만 그린다. 두 번째 Pass인 "ShadowCaster"를 예로 들면, 패스의 Tags 명령에서 LightMode를 ShadowCaster라고 정확히 지정해야 그림자를 캐스팅한다.

 

 

다음은 ShaderLab Pass Tags의 LightMode의 리스트이다.

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

  • UniversalForward: 오브젝트를 렌더링하고 모든 라이팅을 연산한다. Forward 렌더링 패스에 사용한다.
  • UniversalGBuffer: 라이팅 연산 없이 렌더링하며 Deferred 렌더링 패스에 사용한다.
  • UniversalForwardOnly: Forward, Deferred 모두 사용할 수 있다. Deferred 렌더링 패스에서 Forward렌더링 패스가 필요할 때 사용한다. (Clear Coat normals처럼 GBuffer와 맞지 않는 경우, Transparent 렌더링이 필요한 경우)
  • Universal2D: 2D 라이트 연산을 한다. 2D 렌더러에서 사용한다.
  • ShadowCaster: 오브젝트의 깊이를 렌더링하여 Shadow map이나 depth texture에 기록한다.
  • DepthOnly: 카메라 입장에서 깊이 정보를 렌더링해서 depth texture에 기록한다.
  • Meta: 라이트 맵을 구울 때 사용한다. 빌드 시에 이 셰이더는 제거된다.
  • SRPDefaultUnlit(Default): LightMode 태그를 지정하지 않으면 사용되는 디폴트 값이다. 아웃라인을 그리는 경우 등에 사용한다. Forward, Deferred 둘 다 사용 가능하다.

 

 

UsePass "Universal Render Pipeline/Lit/ShadowCaster"

Pass 대신 UsePass가 올 수 있다. Pass 내용을 작성하지 않고 다른 셰이더에서 이미 만든 패스를 가져다 사용하는 방식이다. "셰이더 카테고리/셰이더 이름/PassName" 형식이다.

 

 

Pass Commands

Commands는 패스가 그려질 때 Additive 혹은 Multiply로 그려질지, 뒷면을 그릴지, Z Buffer에 기록과 테스트를 할지 등을 결정하는 부분이다.

Subshader
    {
        Tags { "RenderPipeline" = "UniversalPipeline" "Queue" = "Transparent"}
        Pass
        {
            Blend One One //Additive 방식으로 셰이딩
            ZWrite Off //Z Buffer에 기록하지 않는다.
            Cull Off

 

 

  • Blend: Alpha Blending 제어, Additive/Multiply/Blend 등의 방식이 결정된다.(Unity 매뉴얼)
Blend SrcAlpha OneMinusSrcAlpha //Traditional Transparency
Blend One OneMinusSrcAlpha //Premultiplied Transparency
Blend One One //Additive
Blend OneMinusDstColor One //Soft Additive
Blend DstColor Zero //Multiplicative
Blend DstColor SrcColor //2x Multiplicative

가장 자주 사용되는 형식은 다음과 같다.

Blend <Source Factor(SrcFactor)> <Destination Factor(DstFactor)>
//결과 값 = (SrcFactor * SrcColor) + (DstFactor * DstColor)

 

 

  • Cull: 앞면/뒷면/양면 그릴지 결정한다.
Cull Off //컬링 없이 양면을 다 그린다.
Cull Front //앞면을 컬링하고 뒷면만 그린다.
Cull Back //뒷면을 컬링하고 앞면만 그린다.(Default)

 

 

  • ZTest: Z Buffer 테스트 여부를 결정한다. 가까운 곳이 0, 먼 곳이 1이므로 거리 비교 결과에 따른다.
    • Less: 거리 비교 결과 더 작은 값이면 그린다.
    • LessEqual: 작거나 같으면 그린다. (ZTest On)
    • Disabled: 테스트를 안 하고 무조건 그린다. (ZTest Off)

ZTest 선택지를 선택할 수 있게 만든 예시

 

 

  • ZWrite: Z Buffer에 기록할지 말지 결정한다(On/Off). Additive나 Multiply 방식의 셰이더는 ZWrite Off를 사용한다.

 

  • AlphaToMask: Alpha-to-coverage 모드 설정

 

  • BlendOp: Blend 계산 시 덧셈 대신 다른 연산을 사용할 수 있다.

 

  • ColorMask: 기본적으로 GPU는 RGBA 모든 채널에 기록하는데 특수한 경우 채널을 수정하지 않고 그대로 둘 수 있다.(ex) 색상 렌더링 비활성화로 무색 그림자, 색상 쓰기 완전한 비활성화로 렌더링 없이 Stencil Buffer 혹은 ZBuffer 기록 등)

 

  • Conservative: 픽셀 그릴 때 보수적으로 Resterize 할지를 결정한다. 픽셀이 폴리곤에 조금만 걸쳐있어도 무조건 그린다. 충돌 검사, 가시성 검사에 사용한다.

 

  • Offset: 폴리곤 위에 폴리곤을 그리는 경우에 사용한다.(ex) 데칼 등)

 

  • Stencil: Stencil Test와 Stencil Buffer에 무엇을 기록할지를 설정한다.

 

  • ZClip: 카메라의 Near와 Far 바깥쪽 fragment를 안 그릴지(Clip) 아니면 Near와 Far 거리로 맞출지(Clamp) 결정한다.

 

  • Enum: 열거형의 자료형이다. 에디터에서 Drop-Down 형태로 표시된다.
Shader "Custom/ShaderLab HLSL/PassCommandTest"
{
    Properties
    {
        [MainTexture] _BaseMap("Base Map", 2D) = "white" {}
        [MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)
        [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Float) = 0
        [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull Mode", Float) = 0
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "Queue" = "Transparent"}
        Pass
        {
            Blend One One
            ZWrite Off
            ZTest [_ZTest] // Disabled, Never, Less, Equal, LessEqual, Greater, NotEqual, GreaterEqual, Always
            Cull [_Cull] // 0 OFf, 1 Front, 2 Back

위의 코드에서는 ZTest와 Cull에 Enum을 사용한 것을 볼 수 있다. 만약 Enum이 없으면 Drop-Down 리스트 없이 Float 숫자로 보인다.

 

 

[Enum(AAA, 0, BBB, 4)] _ZTest ("ZTest", Float) = 0

정확한 Enum 인덱스 번호를 사용한다면 사용자가 자유롭게 직접 필요한 키워드 일부만 사용할 수도 있다.(최대 7쌍) Drop-Down 창에 AAA를 선택하면 인덱스 0번(Disabled)이, BBB를 선택하면 인덱스 4번(LessEqual)이 선택되는 것과 같다.

 

 


참고자료

 

아티스트를 위한 유니티 URP 셰이더 입문 - YES24

셰이더(Shader)를 HLSL(High Level Shader Language)로 다루고 싶은 아티스트를 위한 입문서다. 아티스트들의 눈높이에 맞추어 기초 그래픽스 이론과 셰이더 개념을 설명하고, 이를 유니티 엔진에서 활용할

www.yes24.com

 

728x90
반응형