Unity3D 기초 셰이더 스터디를 시작하며...

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


오늘부터 Unity3D의 기초 셰이더 스터디 관련 포스팅을 조금씩 올려보려고 합니다.



보통 Shader라고 쓰고 셰이더라고 읽는 사람도 있고 쉐이더라고 쓰는 사람도 있는데,


Family Mart를 훼미리 마트로 읽던 패밀리 마트로 읽던 쀄멀리 마트로 읽던 중요한건 아닌 것 같습니다.


아니다... 아무래도 훼미리 마트는 좀 문제가 있긴 한 것 같아요.


어쨋든, 발음이 중요한 건 아닌 것 같으니 각자 편한데로 발음 하시면서 따라와 주시면 될 것 같습니다.


저는 그냥 셰이더가 더 편한 것 같아서 셰이더로 표기하며 진행하겠습니다.



셰이더(Shader)가 무엇인가에 대한 정의는 셰이더 관련 서적들을 찾아보면 자세하게 나와있습니다만...


저만의 정의를 내리자면, 게임을 뽀대나게 만들어주는 녀석이라고 할 수 있습니다.


으잉?! 뭐 이딴 정의가 다있어! 라고 하실 수도 있겠지만...


게임 개발자가 셰이더를 사용하는 근본적인 이유는 뽀대나는 게임 개발을 위해서가 주된 이유입니다.


조금 저렴해 보이는 위의 정의를 정리해서 조금 더 고급지게 셰이더에 관한 정의를 내려보자면, 


프로그래머가 자신이 원하는 그래픽 효과의 구현을 위하여 고급 언어를 통해

화면상에 최종적으로 그려지게 될 픽셀의 위치와 색상 정보등을 GPU에게 전달하는 것


이라고 정리를 해 볼 수 있을 것 같습니다.


GPU는 프로그래머가 작성한 셰이더 스크립트를 통해 전달 받은 명령들을


그래픽 데이터를 처리하는 파이프라인을 처리하는 중간 중간마다 적절히 효과를 반영하여 줍니다.


즉,  물체를 렌더링하는 방법을 고급 언어를 통해 프로그래밍 하여 마음대로 변경할 수 있는 것이죠.


그래서 프로그래머블 셰이더(Programmable Shader)라고도 하고요.


어쨋든, 게임 프로그래머에게 있어 셰이더의 주된 목적은 게임을 뽀대나게 만들어주기 위한 것임은 분명합니다.



제가 좋아하는 삽화풍 렌더링으로 유명한 밸브사의 팀포트리스2입니다.


우리 모두 요렇게 뽀대나는 게임 개발을 위해 더 열심히 셰이더 공부해야겠네요.



Unity3D는 ShaderLab 이라는 유니티 자체적인 셰이더 개발 환경을 제공하고 있습니다.


보통 HLSL이나 CG 등의 셰이더 언어를 떠올리시는 분들도 있으시겠지만...


GPU 단에서는 .Net Framework과 같이 가상 머신을 구성할 수 없기 때문에 셰이더랩(Shader Lab)이라는


자체 셰이더 스크립트 형식을 사용하여 크로스 플랫폼을 커버하고 있습니다.



일단 유니티를 설치하시고 실행해 봅시다.


잠수함 패치의 대명사 유니티인 만큼, 가급적 스터디는 최신 버전에서 진행하겠습니다.


프로젝트 이름은 본인이 원하시는 걸로 입력하시고 새 프로젝트를 열어봅시다.



위와 같은 유니티 화면이 나왔죵?


유니티의 기초적인 화면 구성이나 개발 방법등에 대해서는 구글링해보면 수많은 자료가 있으니


여기서 언급하는 것은 생략하도록 하겠습니다.


혹시 여유가 되서 유니티 기초 스터디 노트도 작성할 수 있다면, 그 때 한번 다뤄야 겠네요.



일단 기본적인 프로젝트 구성을 위해 다음과 같이 폴더 구성을 하시고 따라와 주세요.



보통 저는 Scenes폴더와 Scripts 폴더를 최상단에 표시되게 하기 위해서 


폴더 이름 앞에 느낌표(!)를 붙여주는데요.


느낌표가 없으면 Scenes 폴더와 Scripts 폴더가 Resources 폴더 밑에 위치하게 되서 불편하더라구요.


개인적인 취향이니 느낌표와 같은 폴더 네이밍은 본인이 편하신데로 하시면 됩니다.


안붙이셔도 되고, 언더바(_) 등으로 대체하셔도 되고... 개인의 취향을 존중합니다.


File > Save Scene 혹은 Ctrl + S를 눌러 지금 현재 씬을 Scenes 폴더에 저장해두었습니다.



Shaders 폴더 위에서 마우스 우클릭 > Create > Shader > Standard Surface Shader 클릭.


Shader 파일 이름은 간단히 BasicShader라고 해둡시다.



그럼 위와 같이 Shaders 폴더 안에 BasicShader라는 셰이더 스크립트가 생성 되었죠?


위 그림과 같은 상태가 되었다면, 생성된 셰이더 파일을 더블 클릭해서 편집해봅시다.


쏼라쏼라... 알 수 없는 코드들을 오늘은 일단 과감히 지워주시고 아래 코드를 붙여 넣어주세요.


Shader "LimePapa/BasicShader"

{

    Properties

    {

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

    }


    SubShader

    {

        Pass

        {

            Material

            {

                Diffuse[_Color]

            }


            Lighting On

        }

    }


    Fallback "Diffuse"

}


어떤 내용인지 정확히는 몰라도, 일단 코드가 짧으니 대충 눈에 잘 들어오죠?


일단 코드 설명은 뒤로 하고 일단 이 셰이더를 사용할 매터리얼을 만들어봅시다.



당연히 Materials 폴더 위에서 우클릭 후, Create > Material 하면 매터리얼이 추가되겠죠?


저는 위와 같이 BasicShader라고 셰이더와 같은 이름의 매터리얼을 만들었습니다.



BasicShader 매터리얼 파일을 선택해보면, 현재 셰이더터가 Standard 로 설정되어 있습니다.


왼쪽 클릭해서 셰이더 파일을 바꿔 줍시다.


신기하게도 LimePapa라는 폴더가 생기고 그 안에 BasicShader가 들어가있네요.


맞습니다. 아까 저희가 작성한 셰이더 코드에 아래와 같이...


Shader "LimePapa/BasicShader"

{

    .....

}


Shader 이름을 "LimePapa/BasicShader"로 지정했을 뿐인데, 저런식으로 계층구조로 표시되네요.


신기방기하네요. 어쨋든 BasicShader를 선택해보면 아래와 같은 화면을 보실 수 있으실꺼에요.



매터리얼 인스펙터 창에서 복잡한 내용이 다 빠지고 Color 입력 받는 것 하나만 남았네요.


Shader "LimePapa/BasicShader"

{

    Properties

    {

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

    }


    .....

}


저희가 아까 Shader 스크립트의 Properties 안에 _Color라고 변수를 선언해 두었었는데


유니티가 인스펙터 창에서 입력받을 수 있는 UI를 자동으로 제공해주네요. 굿굿!


어쨋든 그렇다면, 저는 Color 값을 아래와 같이 빨간색으로 바꾸어 볼께요.



저는 RGB(255, 0, 0)의 기본 빨간색으로 지정했지만, 아무 색이나 원하는 색으로 하셔도 상관 없어요.


자 이제 이 셰이더를 적용시킬 Cube를 하나 추가 해 볼께요.



유니티 기초를 다루는 건 아니지만, 첫 스터디다 보니 약간은 쓸데 없이 친절해지게 되네요...


Hierachy 창에서 우클릭 후, 3D Object > Cube인거 다들 아실 거라 믿습니다.



Mesh Render 컴포넌트 안의 Material을 우리가 만든 BasicShader로 교체하니...


위 처럼 큐브가 빨갛게 변했네요.


Shader "LimePapa/BasicShader"

{

    ...


    SubShader

    {

        Pass

        {

            Material

            {

                Diffuse [_Color]

            }


            Lighting On

        }

    }


    ...


}


위의 셰이더 코드 중 SubShader 블럭 안의 Pass가 처리된 것 같네요.


Pass는 그야말로 물체를 그릴 때 GPU에 넘겨줄(Pass) 작업들을 담고 있는 녀석이구요.


만약 하나의 물체에 대해 두번 이상으로 나누어 그려야 하는 경우라면?!


단순히 여러 개의 Pass를 작성해 주면 됩니다. 이런 것을 멀티 패스라고 합니다.



일단 첫 스터디니 먼저 간단히 위의 코드를 먼저 살펴보겠습니다.


먼저 Material 블럭 안에서는 재질을 설정할 수 있습니다.


재질 중에 Diffuse 속성의 컬러 값을 앞전에 우리가 받은 컬러 값으로 지정해주고,


라이트를 켜준게 끝입니다.



결과는 위와 같구요. 간단하죠?


Shader "LimePapa/BasicShader"

{


    ...


    Fallback "Diffuse"

}


그리고 제일 마지막 라인에 Fallback 이라는 구문이 보이는데요.


만약 SubShader에 구현한 내용들이 그래픽 하드웨어에서 지원하지 않는 등의 이유로


정상적으로 동작하지 않는 상황이 되면 유니티 엔진은 Fallback에 지정된 이름의 셰이더를 찾고,


해당 셰이더를 실행게 됩니다. 그 셰이더도 실행이 불가능하면 또 Fallback을 찾겠죠?



대충 어떤 역할을 하는 녀석인지 아시겠죠?


쉽게 말해 이 셰이더가 동작하지 않으면 대신이 이 셰이더를 사용하라고 보험을 들어두는 역할입니다.


이런 식으로 Fallback 셰이더를 지정해두면, 셰이더가 정상적으로 실행하기 힘든 하드웨어 환경에서


아무것도 그려주지 못하게 되는 상황을 막아주고, 낮은 품질으로라도 렌더링 할 수 있게 도와줍니다.



오늘은 엄청나게 대충...


말 그대로 수박 겉핥기 식으로 유니티 프로젝트를 세팅해서 셰이더 파일을 작성해보고,


대략적인 유니티 셰이더 스크립트의 구조를 훑어 보았습니다.


다음 포스팅에서는 좀 더 세부적인 내용을 스터디 해보도록 하겠습니다


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


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


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


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


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

이 글을 공유하기

댓글

Designed by CMSFactory.NET