고정 함수 셰이더 (Fixed Function Shader) 스터디

안녕하세요. 연두아빠에요.


이제 길고 길었던 백수 생활을 청산해야 할 때가 얼마 남지 않아서 정신이 없네요.


거기에 대통령 선거에 어린이날까지 겹쳐 며칠 블로그에서 손을 떼게 되었습니다.


더이상 쉬게 되면 또 블로깅 한동안 뜸해 질 것 같아 부랴부랴 포스팅 하는 중입니다.



유니티에서 셰이더를 작성하는 방법은 크게 두가지로 나눌 수 있습니다.


  1. 고정 함수 셰이더 스크립트 사용하는 방법
  2. CG 셰이더 스크립트를 사용하는 방법


고정 함수 셰이더는 Unity3D에서 미리 만들어 놓은 함수들을 나열하여 작성하게 됩니다.


이름 그대로 고정된 함수(Fixed Function)이기에 각각의 함수들으 커스터마이징이 불가능합니다.


반면에 유니티가 각 플랫폼에 맞게 최적화 해놓은 함수들이기에 처리 속도가 매우 빠르고,


낮은 성능의 디바이스에서도 잘 동작한다는 장점이 있습니다.


또한 그냥 필요한 기능에 해당하는 함수들을 나열하면 되기 때문에 간편하게 작성이 가능하구요.


그러나 역시나 고급 효과를 작성할 때에는 여러모로 제약이 많아 보통은 CG 셰이더를 많이 사용합니다..


그러나 간단한 내용의 셰이더라면, 고정 함수 셰이더로 작성했을 때 얻어지는 이점이 꽤나 크기에


무시하고 넘어가기엔 존재 가치가 분명한 녀석이므로, 대략이라도 훑고 지나가봅시다.



먼저, 지난 스터디에서 살펴보았던 것과 같이 기본적인 프로젝트 세팅을 해주세요.



프로젝트, 씬, 매터리얼, 셰이더 전부 이름은 마음대로 하셔도 됩니다.


일단 저는 앞으로 대충 이런 식으로 기본 프로젝트를 구성하고 스터디를 진행할 예정이니 참고 부탁드립니다.


먼저 Resources/Textures 폴더에 아래의 박스 텍스쳐를 받아 넣어주세요.



먼저, 위의 박스 텍스쳐를 이용해서 간단한 텍스쳐 맵핑 셰이더를 만들어 볼께요.


Scripts/Shaders 폴더에 MyUnlitTex 라는 이름의 셰이더 파일을 만들고 아래와 같이 입력해주세요.


Shader "LimePapa/MyUnlitTex"

{

    Properties

    {

        _MainTex ("Base (RGB)",  2D) = "white" {}

    }


    SubShader

    {

        Pass

        {

            Lighting Off

            SetTexture [_MainTex]

        }

    }

}


간단하죠? 이것이 고정 함수 셰이더의 가장 큰 장점입니다.


누가 봐도 무슨 역할을 하는 셰이더인지 단번에 알아 차릴 정도로 심플합니다.


라이팅을 사용하지 않을 것이고, 프로퍼티 창에서 입력받은 텍스쳐를 적용해주는 스크립트입니다.



셰이더 이름으로 지정해준 "LimePapa/MyUnlitTex" 경로에 방금 만든 셰이더가 있습니다.


미리 만들어 놓은 매터리얼에 해당 셰이더를 적용하고 박스 텍스쳐를 설정합니다.



다들 잘 따라오셔서 위와 같이 세팅이 되셨으리라 믿습니다.


이제 큐브의 매터리얼을 설정해줍시다.


매터리얼을 설정하는 방법은 두가지가 있습니다.


  1. 매터리얼을 씬이나 하이어라키 윈도우의 객체에 드래그하는 방법.

  2. 메쉬 렌더러(Mesh Renderer)의 매터리얼을 직접 설정해주는 방법.



위의 그림의 화살표가 가리키는 3군데 중 아무데나 매터리얼을 드래그해주면 세팅이 됩니다.


어때요? 참 쉽죠?


나머지 코드는 그렇다 치고, Pass 블럭 안에 딱 두줄 입력했는데 이렇게 멋진 박스를 만들었습니다.



이번엔 라이팅 계산을 한번 추가해볼까요?


마찬가지로 Scripts/Shaders 폴더에 MyVertexLit 이라는 이름의 셰이더를 만들고 아래처럼 입력합니다.


Shader "LimePapa/MyVertexLit"

{

    Properties

    {

        _Color ("Color",  Color) = (1, 1, 1, 1)

        _MainTex ("Base (RGB)",  2D) = "white" {}

    }


    SubShader

    {

        Pass

        {

            Material

            {

                Diffuse [_Color]

                Ambient [_Color]

            }


            Lighting Off

            SetTexture [_MainTex]

        }

    }

}


지난 시간에 살짝 살펴본 재질 관련 코드를 위와 같이 입력해줘봤습니다.


마찬가지로 별거 없습니다.


Diffuse, Ambient 컬러를 프로퍼티로 입력 받은 컬러 값으로 설정해주는게 끝입니다.


매터리얼에 LimePapa/MyVertexLit 셰이더를 적용해주면 이제 정점 라이팅이 적용되어...



오잉?! 우리가 설정한 라이팅 설정 내용이 제대로 적용이 안되어 있네요!


SetTexture 앞에 주석 처리를 해보면, 분명 라이팅 연산이 정상적으로 이뤄지고 있는걸 볼수 있습니다.




SetTexture를 거치면서 라이팅 연산 결과를 텍스쳐의 컬러 값들로 덮어 씌워버린 것 같습니다.


텍스쳐를 설정할때, 텍스쳐의 컬러 값에 이전에 계산한 컬러 값을 적용시켜주는 작업이 필요할 것 같습니다.


MyVertexLit 스크립트의 코드를 아래 처럼 수정해 보겠습니다.


Shader "LimePapa/MyVertexLit"

{

    Properties

    {

        _Color ("Color",  Color) = (1, 1, 1, 1)

        _MainTex ("Base (RGB)",  2D) = "white" {}

    }


    SubShader

    {

        Pass

        {

            Material

            {

                Diffuse [_Color]

                Ambient [_Color]

            }


            Lighting Off

            SetTexture [_MainTex] { Combine texture * primary }

        }

    }

}


기존의 SetTexture 관련 코드 뒤에 뭔가 새로운 코드 블럭이 더 붙었네요.


일단 이해하는 건 뒤로 미루고, 결과를 먼저 보면...



정상적으로 텍스쳐가 맵핑된 상태에서 라이팅 연산까지 적용이 되었네요.


SetTexture [_MainTex] { Combine texture * primary }


Combine 명령어를 통해서 텍스쳐를 설정할 때 컬러 값을 어떻게 조합할지 지정할 수 있습니다.


texture 키워드는 말 그대로 텍스쳐의 컬러 값을 의미하고, primary는 라이팅 계산 결과를 의미합니다.


그런데 라이트 컬러에 텍스쳐 컬러를 섞어주면서 뭔가 전체적인 컬러감이 많이 어두워졌네요.


Combine을 이용해 곱셈 계산을 하는 경우에는 기존 컬러 값보다 반드시 어두워 지게 됩니다.


컬러 값이 0.0 ~ 1.0 사이의 값을 갖으므로 두 소수를 곱하면 둘다 0 또는 1인 경우를 제외하고는


반드시 결과 값이 기존 보다 작은 값이 나올 수 밖에 없겠죠?


그래서 보통 두 컬러를 곱하고 나면 결과 값에 두배를 곱해주어 밝게 만들어 줍니다.


SetTexture [_MainTex] { Combine texture * primary DOUBLE }


위와 같이 컬러 계산 공식의 맨 뒤에 DOUBLE을 써주면 끝입니다.



어때요? 앞전의 것 보다 좀 더 밝아졌네요. 훨씬 그럴듯 해 보입니다.


오늘은 고정함수 셰이더를 이용해서 간단히 물체에 텍스쳐와 정점 라이팅 연산을 적용해보았습니다.



원래라면 라이트의 위치와 노멀 등을 계산해서 곱해주는 등의 작업을 수동으로 해주어야했겠지만,


이처럼 고정 함수 셰이더를 이용하면 미리 만들어진 최적화 된 함수들을 단순히 호출해주면 끝입니다.


덕분에 간단히 원하는 그래픽 효과의 구현이 가능합니다.


반면에 내장 함수들의 커스터마이징에 한계가 있다보니 좀 더 자유로운 확장이 힘들다는 단점도 있구요.


오늘 스터디한 것만 가지고는 고정 함수의 장단점이 확 와닫지 않는 것 같습니다.


다음 시간에 조금 더 고정 함수를 가지고 놀며 느껴봐야겠네요.


공감() 및 댓글은 글쓴이에게 커다란 힘이 됩니다.


길지 않은 이 글을 쓰는데 나름 몇 시간이 걸렸어요^^;


저에게 1초만 시간을 내주셔서 공감 버튼 꾸욱 눌러주세요^^


제 블로그를 방문해 주신 모든 분들 사랑합니다^^


이상입니다. 감사합니다!

이 글을 공유하기

댓글

Designed by CMSFactory.NET