본문 바로가기
유니티/Shader Study

URP Shader Study #1 (Queue, RenderType, Pass)

by witn331ss 2023. 11. 29.
 // Shader 시작. 셰이더의 폴더와 이름을 여기서 결정합니다.
Shader "URPTraining/URPBasic"
{


   Properties
             {   
// Properties Block : 셰이더에서 사용할 변수를 선언하고 이를 material inspector에 노출시킵니다
           	}  

	SubShader
	{  

	Tags
            {
//Render type과 Render Queue를 여기서 결정합니다.
	   "RenderPipeline"="UniversalPipeline"
                "RenderType"="Opaque"          
                "Queue"="Geometry"
            }
    	Pass
    	{  		
     	 Name "Universal Forward"
              Tags { "LightMode" = "UniversalForward" }

       	HLSLPROGRAM

        	#pragma prefer_hlslcc gles
        	#pragma exclude_renderers d3d11_9x
        	#pragma vertex vert
        	#pragma fragment frag

//cg shader는 .cginc를 hlsl shader는 .hlsl을 include하게 됩니다.
       	#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"        	
  
//vertex buffer에서 읽어올 정보를 선언합니다. 	
         	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  
    	}
     }
}

변수명은 대소문자를 구별한다.

변수타입의 선언은 대소문자 구별을 안한다. ex : Range(0,1))..

 

Properties

쉐이더 계산에 사용되는 변수를 넣는 곳.

 

 

 

SubShader

쉐이더 블록을 선언하는 것이 SubShader

 Tag {"RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" "Queue"="Geometry"}

이렇게 세개가 기본으로 들어가는데

테깅에 들어가는 것들은 미드텀에 들어가게 되면 훨씬 더 많이 들어가게 된다.

 

렌더 파이프라인에 이 서브쉐이더를 사용할 때 유니티에 선언하게 된다.

(렌더 파이프라인을 선언하지 않아도 작동은 되긴 함)

 

Q :TAG 안적어도 기본으로 설정이 됨?

A : dd 기본적으로 설정이 됨 기본 쉐이더는 아무것도 태깅되지 않아도 자동으로 선언해주긴 함

 

##

Rendering Order :: Queue TAG

Queue Tag를 사용해 '오브젝트를 그리는 순서'를 결정할 수 있다.

이는 오브젝트가 속한 '렌더 대기열'을 결정하게 된다.

 

Background(1000) 다른것들보다 먼저! 렌더링 하게된다. 일반적으로 백그라운드에 있어야 하는 작업에 사용된다
Geometry(Default~2000) 대부분의 불투명 오브젝트에 해당된다. 기본값
AlphaTest(2450) 알파 테스트를 거친 Geomatry는 이 큐값을 사용하게 된다.
모-든 불투명 오브젝트를 그린 후

알파테스트된 오브젝트를 렌더링 하는 것이 효율적이기 때문에
이를 별개의 큐로 구분해서 사용한다.
Transparent(3000) Geometry 및 AlphaTest 이후 이 렌더 큐 항목은 '뒤'에서 '앞'의 순서로 렌더링하게 된다.
알파 블렌딩된 모든 것들 (deoth buffer에 사용하지 않은 쉐이더 등?)은 여기로 이동한다.
(유라, 파티클 이펙트 등)
Overlay(4000) 오버레이 효과를 위한 것으로 마지막으로 렌더린 된 모든 항목은 여기에 해당된다/
(렌즈 플레어 등)

 

 

Render Type

RenderType 태그는 쉐이더를 -> 미리 정의 된 여러 그룹으로 분류하게 된다.

불투명한 쉐이더 또는 알파 테스트를 거친 쉐이더 등이 여기에 해당되며, 이것은 쉐이더 교체에서 사용되거나

경우에 따라선 카메라의 depth texture를 생성하는데 사용된다.

Opaque 대부분의 불투명 쉐이더
Transparent 대부분의 반투명 쉐이더
TransparentCutout mask된 투명 쉐이더 (AlphaTest된 쉐이더가 해당됨)
Background skybox shader
Overlay Halo, Flare shader
TreeOpaque 터레인에서 나무와 줄기부분
TreeTransparentCutout 터레인의 잎부분
TreeBillboard 터레인의 빌보드된 나무
Grass 터레인의 풀
GrassBillboard 터레인의 빌보드된 풀

 

 

Pass

 

컴퓨터 그래픽스에서는 우리가 보는 한 프레임을 만들기 위해서는 많은 순서를 거쳐야한다.

Window -> Analysis -> Frame Debugger

 

선언한 것들을 거기에 맞춰서 순서대로 그리는 과정이고

그 프레임 안에서 그리는 순서를 쪼개놓은 단계들이 바로 패스이다.

 

URP버전이 올라감에 따라서 내부패스가 바뀜에 따라서 바뀐다

업데이트 보고 변한거 없나 둘러봐야함 ㅠㅠ

 

 

SubShader
    {
       Tags { "RenderType" = "Opaque"
                  "RenderPipeline" = "UniversalPipeline"
                  "UniversalMaterialType" = "SimpleLit" 
                  "IgnoreProjector" = "True"
                   "ShaderModel"="4.5"}
        Pass
        {
           Name "ForwardLit"
           Tags { "LightMode" = "UniversalForward" }
           …
        }
   
        Pass
        {
            Name "ShadowCaster"
            Tags{"LightMode" = "ShadowCaster"}
          …
        }
       Pass
        {
            Name "GBuffer"
            Tags{"LightMode" = "UniversalGBuffer"}
        …
        }
       Pass
       {
            Name "DepthOnly"
            Tags{"LightMode" = "DepthOnly"}
       …
       }

 

lit은  라이팅을 의미하는 것임

쉐도우캐스터는 그림자 그리는거고

지버퍼는 지버퍼에 정보를 넣을때 필요한 것을 만드는 것이고

뎁스패스는 뎁스를 만드는 것이라고 알아는 두면 됨