Contents

[클라우디아 도피오슬래시]유니티 물리 기반 셰이더 개발 02

   Apr 27, 2023     5 min read     - Comments

생성 및 적용


  • Asset - Create - Material
    Material 생성
  • Asset - Create - Shader - Unlit Shader
    Shader 생성
  • Asset - 생성한 Material 선택 - Inspector - Shader - 생성한 Shader 선택
    Shader 선택


Unlit


Shader "Unlit/Shader이름"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

셰이더 경로와 이름

Shader "Unlit/Shader이름"


특성

Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }

인스펙터 창에 보여질 각각의 특성을 여기에서 선언한다.


하위 셰이더

SubShader
    {

여기에는 한 개 이상의 셰이더 내의 하위 셰이더(Sub-Shaders)를 둘 수 있다.


태그

Tags { "RenderType"="Opaque" }

태그는 정보를 표현하는 키와 값의 쌍으로 구성돼 있다. 예로는 어떤 렌더링 큐를 사용할지에 대한 것을 들 수 있다. 투명 및 불투명 게임 오브젝트는 각기 다른 렌더링 큐에서 렌더링된다.


Pass

Pass
{

각각 패스는 렌더링을 위한 정보와 실제로 셰이더에서 계산하는 코드와 같은 정보들을 포함한다.


CGPROGRAM과 ENDCG

CGPROGRAM과 ENDCG는 명령어의 처음과 끝을 나타넨다.


pragma선언
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

정점 셰이더와 픽셀 셰이더에 사용할 함수들을 지정하는 것과 같은 옵션 설정방법을 제공한다. 이는 셰이더 컴파일러에게 정보를 전달하는 방법이다.


Includes
#include "UnityCG.cginc"


입력과 출력 구조체
struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
};

struct v2f
{
    float2 uv : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    float4 vertex : SV_POSITION;
};

정점 셰이더는 프레그먼트 셰이더로 구조체를 통해 정보를 전달한다. v2f가 그 구조체다.
정점 셰이더는 입력 구조체를 통해 특정 정보를 요청할 수 있다. appdata가 그 구조체다.

SV_POSITION과 같이 세미콜론 다음에 오는 단어들을 시맨틱(semantics)이라고 한다. 컴파일러에게 구조체 내 특정한 맴버 내에 어떤 종류의 정보를 저장하고자 하는지 알려준다. SV의 뜻은 System Value이다.


변수 선언
sampler2D _MainTex;
float4 _MainTex_ST;


정점 함수와 프레그먼트 함수
v2f vert (appdata v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
}

fixed4 frag (v2f i) : SV_Target
{
    // sample the texture
    fixed4 col = tex2D(_MainTex, i.uv);
    // apply fog
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}


셰이더 수정


Shader "Unlit/RedShader"
{
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return fixed4(1, 0, 0, 1);
            }
            ENDCG
        }
    }
}


속성추가

하드코딩은 좋은 습관이 아니다. 원하는 색상으로 변경 가능 할 수 있는 셰이더로 변경하자.

Properties
    {
        _Color("Color", Color) = (1, 0, 0, 1)
    }

속성 블록은 _이름(“설명”, 타입) = 기본값 으로 구성된다. 속성의 종류에는 텍스처, 색상, 범위, 숫자를 포함하며 매우 다양하다.

fixed4 _Color;

CGPROGRAM 뒤쪽 어딘가에 선언을 추가한다.

fixed4 frag (v2f i) : SV_Target
{
    return _Color;
}

이제 재질 인스팩터 패널에서 색상을 선택할 수 있다.

이 셰이더에는 다른 유니티 셰이더들과 마찬가지로 두 가지 언어가 섞여 있다. 하나는 Cg 라는 NVIDIA에서 개발한 셰이더 언어이다. CGPROGRAM과 ENDCG문 사이에 있는 것들이 이 언어로 작성됐다.
다른 하나는 셰이더랩(ShaderLab)언어이고, 유니티에서만 사용하는 Cg를 확장한 언어이다. CGPROGRAM 바깥쪽에 있는 모든 코드가 이 언어로 작성됐다.