0503 쉐이더 기본

2021. 5. 3. 09:41unity/쉐이더

픽셀의 색을 정해주는 함수

Draw Call
드로우 콜이 높아질 수록 성능이 저하된다.
텍스쳐 1장당 1개의 드로우 콜이 생겨나므로, 아틀라스를 이용해 작업하면 드로우콜이 낮아진다.

랜더링 파이프라인
3D가상 공간의 물체를 화면의 픽셀의 색으로 출력하는 과정

1. 오브젝트 데이터를 받아온다.
2. 버텍스 쉐이더를 계산한다. (점들의 좌표 위치 계산)
3. 래스터라이즈 (만들어낸 면을 쪼개어 색을 칠할 수 있도록 편집)
4. 픽셀 쉐이더/프래그먼트 쉐이더 (텍스쳐를 칠한다.)

한 개의 픽셀은 3개의 서브픽셀로 이루어져 있다.
컬러들을 숫자로 인식한다.
한 픽셀의 색을 결정하는 코드를 픽셀 쉐이더라고 부른다.

Adobe RGB(255,255,255) > float3(1.0,1.0,1.0)
으로 색상 연산이 가능하다.

ex) float3(0.5,0.5,0.5)+float3(0.5,0.5,0.5)=float3(1.0,1.0,1.0) > 흰색

 

쉐이더 스크립트 생성
각각 assign 해주기

 


※쉐이더는 비쥬얼 스튜디오에서 오류 표시나 도움을 받을 수 없으니 참고 바람. (작동 안 되는 게 아님!)

쉐이더 코드 판의 구성

property는 유니티의 Inspecter 창에서 나타나는 부분

인스펙터에 칼라 선택 창이 생겼다.

 

인스펙터에 슬라이더가 생겼다.

 

소수를 입력받는 칸이 생겼다.

 

정수를 입력받는 칸이 생겼다.

 

벡터값을 입력받는 칸이 생겼다.

 

 

input은 유니티 엔진으로부터 들어오는 데이터.
색상과 이미지를 출력하는 부분은 surf 함수 부분

SurfaceOutputStandard
7개의 변수 중 가장 중요한 2개:
Albedo > 물체가 빛을 받았을 때 반사하는 정도
Emission > 표면에 방출되는 빛의 색상과 강도를 제어

 

기본 rgb 순으로 여긴다. 위의 r값=1이므로
붉은 색으로 출력된다.

 

Emission과 Albedo의 차이점

 

rgb 값은 연산이 가능하다. 지금은 r과g를 더해 노랑을 출력했다.

 

소숫점끼리 더해 rgb가 (1,1,1)이 되자 흰색이 되었다. 

 

rgb 값끼리 곱했더니 색이 어두워졌다. 포토샵에서 레이어 타입 multuply와 같은 원리이다.

 

이런 색상이 존재하는 상태, 즉 1보다 밝은 색이 있고 0보다 어두운 색이 있어서 계산되는 상태를 HRD(Hight Dynamic Range)라고 한다.

 

이런 식으로도 연산이 가능하다.
결과는 똑같다.

 

주석과 아래는 같은 공식이다.

 

이렇게도 표현이 가능하다.

 

hader "Custom/Test"
{
    Properties
    {
        _TestColor ( "Test Color",Color)=(1,1,1,1)
    }
    

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows


        struct Input
        {
            float2 uv_MainTex;
        };

        float4 _TestColor;



        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo = _TestColor.rbg;
            o.Alpha = _TestColor.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 


 

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Red ("Red",Range(0,1))=1
        _Green ("Green",Range(0,1))=1
        _Blue("Blue",Range(0,1))=1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        
        #pragma surface surf Standard fullforwardshadows



        struct Input
        {
            float2 uv_MainTex;
        };

        float _Red;
        float _Green;
        float _Blue;


        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo = float3(_Red, _Green, _Blue);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Red ("Red",Range(0,1))=1
        _Green ("Green",Range(0,1))=1
        _Blue("Blue",Range(0,1))=1
        _BD ("Brightness & Darkness",Range(-1,1))=0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        
        #pragma surface surf Standard fullforwardshadows



        struct Input
        {
            float2 uv_MainTex;
        };

        float _Red;
        float _Green;
        float _Blue;
        float _BD;


        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo = float3(_Red, _Green, _Blue) + _BD;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

 

Shader "Custom/Test"
{
    Properties
    {
        
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        
        #pragma surface surf Standard fullforwardshadows


        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };



        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = (c.r + c.g + c.b) / 3; 
            //rgb의 평균값을 낸다는 뜻은 흑백으로 만든다는 뜻

        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

Shader "Custom/Test"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _MainTex2 ("Texture 2nd", 2D) = "white" {}
        _MixAmount("Mix Amount",Range(0,1)) = 0
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        
        #pragma surface surf Standard fullforwardshadows

        sampler2D _MainTex;
        sampler2D _MainTex2;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainTex2;
        };

        float _MixAmount;
        
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D(_MainTex2, IN.uv_MainTex2);
            o.Albedo = lerp(c.rgb, d.rgb,1-c.a);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

두 개의 텍스쳐를 섞었다.
반전
1. 원본 / 2. 알파값 반전
이 알파값을 반전시키는 것임.
이러면 흙밭에 풀이 나 있는 걸 코드 하나로 더 쉽게 표현할 수 있겠다.

 

Shader "Custom/Test"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _MainTex2 ("Texture 2nd", 2D) = "white" {}
        _MixAmount("Mix Amount",Range(0,1)) = 0
        _BG ("Brightness for Ground",Range(-1,1)) = 0
        _Grass ("Brightness for Grass",Range(-1,1)) = 0
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        
        #pragma surface surf Standard fullforwardshadows

        sampler2D _MainTex;
        sampler2D _MainTex2;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_MainTex2;
        };

        float _MixAmount;
        float _BG;
        float _Grass;
        
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D(_MainTex2, IN.uv_MainTex2);
            o.Albedo = lerp(c.rgb+_Grass, d.rgb + _BG, 1 - c.a);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

흙과 풀잎의 밝기를 따로 조절할 수 있게 했다.

 

rgb값의 평균을 구하면 흑백이 된다.