고정 함수 셰이더를 이용한 노멀맵 적용

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


이번 시간은 지난 시간 결과물에 이어서 작업을 해보겠습니다.


지난 시간 작업 했던 내용을 열어주세요. 혹시 저장 안하신 분들은 없으시리라 믿습니다.



지난 시간 결과물은 위와 같습니다.


정확히 말하면 마지막 결과물은 초록색 나무 박스이지만...


초록색 나무 박스는 좀 혐오스러운 면이 없지 않으니 다시 컬러 값을 화이트로 바꿔주세요.



오늘 스터디는 이 장면에서 이어서 바닥을 깔아보도록 하겠습니다.


먼저 Plane 하나를 만들어 바닥으로 배치를 해 주시고,


바닥면 재질 설정을 위한 Floor라는 이름의 매터리얼도 하나 만들어서 Plane에 적용해 주세요..


매터리얼의 셰이더는 우선은 지난 시간에 만들었던 MyVertexLit 셰이더를 적용합시다.


바닥 텍스쳐는 아래 타일 이미지를 사용하면 예쁠 것 같네요.



구글에서 나름 심혈을 기울여 무료로 사용해도 된다고 허가가 난 타일 이미지를 찾았습니다.


자, 지금까지의 과정을 모두 잘 따라 오셨다면...


적당히 아래와 비슷한 결과 화면이 보이실거에요.



다들 잘 따라오고 계시죠?


배치도 실력입니다. 여러분! 난 프로그래머니 미적 감각은 필요없다 주장하지들 마시고...


최대한 카메라랑 상자의 위치, 회전 값 등을 적당히 변경해서 예쁘게 배치해보세요.


꼭 저와 똑같이 배치할 필요는 없습니다^^



오늘은 저 바닥면에 노멀맵을 입혀볼까 합니다.


노멀맵이 뭐냐고요? 아... 음... 그... 파란 텍스쳐... 반짝 반짝... 고퀄 게임 개발을 위한... 음...


자! 네이버에서 검색해봅시다.


네이버 지식백과의 노멀맵에 관한 설명은 아래 링크에서 확인하실 수 있습니다.


http://terms.naver.com/entry.nhn?docId=2028711&cid=42914&categoryId=42916



노멀맵 (Normal Map)이란 노멀 범프 맵 (Normal Bump Map)의 약자로, 


적은 수의 폴리곤(polygon)으로도 높은 퀄리티(quality)의 모델링(Modeling)을 가능하게 만들어주는


그래픽(Graphic) 기술의 일종을 말한다.



오호! 제가 말했던 파란 텍스쳐... 반짝 반짝... 고퀄 게임... 이게 정답이었네요!


적은 수의 폴리곤으로도 높은 퀄리티의 모델링을 가능하게 만들어주는 슈퍼 울트라 멋진 녀석이랍니다.


어디 정말 그런지 유니티 공식 사이트에 기재된 노멀맵 관련 설명을 참고해 보겠습니다.



좌쪽의 일반 입체감 없고 볼품 없는 텍스쳐와 우측 노멀 맵을 적절히 적용해주면...



짠! 이런식의 결과물의 구현이 가능합니다!


여러분 사기 치는게 아니고 진짜 위의 볼품없던 저 텍스쳐 맞습니다....


그렇다고 메쉬를 굴곡있게 만든 것이냐 하면... 그것도 아닙니다.



보셨죠? 노멀맵이 적용되지 않은 상태를 보시면, 많은 수의 폴리곤을 사용하지 않은 평평한 벽면입니다.


위 내용 관련해서는 유니티 공식 사이트 노멀맵 섹션에서 확인하실 수 있습니다.


https://docs.unity3d.com/Manual/StandardShaderMaterialParameterNormalMap.html


진짜 볼품 없던 텍스쳐로 저 정도의 퀄리티를 낼수 있다는게 놀랍지 않나요?



백문이 불여일견이라고 하잖아요. 대충 위에 이미지를 보니 노멀맵이 어떤 놈인지 감이 오시죠?


노멀맵은 이처럼 굴곡이 없는 표면에 복잡한 형상이나 무늬의 굴곡이 있는 것처럼 보이게끔 해줍니다.


실제 오브젝트에는 아무런 변화를 주지 않고, 단순히 텍스쳐 맵핑으로 눈속임을 해주는 일종의 트릭이죠.


그러다보니 처음 공부할 때나 지금이나 노멀맵을 적용하고 나면 언제나 뿌듯함이 밀려오곤 합니다.



일단 이번 스터디에서는 노멀맵이 무엇인지 정확한 정의 같은 것은 스킵하고 넘어갈께요.


지금은 단순히 유니티 셰이더에 대한 감 익히기 정도의 단계이니 일단 진도 팍팍 빼고...


향후에 노멀맵이나 기타 키워드에 대해서는 별도의 아티클로 정리를 해보는 쪽으로 진행하겠습니다.



어쨋든, 이제 우리가 만들고 있는 프로젝트로 돌아와서...


우리 바닥에도 저렇게 뽀대나는 범프 맵핑을 적용해 볼까요?



이 놈이 아까 바닥에 깔았던 텍스쳐의 노멀맵 텍스쳐입니다.


역시나 다운 받으셔서 Resources/Textures 폴더에 넣어 주시구요.


기초 과정이지만, 설마 텍스쳐를 Scripts 폴더에 넣으시는 정도의 분들은 안계시리라 믿습니다...



다음으로 정말 간단히 노멀맵 텍스쳐를 적용해주는 코드를 작성해 봅시다.


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


Shader "LimePapa/MyBumpedMap"

{

    Properties

    {

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

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

        _BumpedTex ("Bumped (RGB)",  2D) = "white" {}

    }


    SubShader

    {

        Pass

        {

            Material

            {

                Diffuse [_Color]

                Ambient [_Color]

            }


            Lighting On


            SetTexture [_BumpedTex]

            SetTexture [_MainTex] { Combine texture * previous DOUBLE }

        }

    }

}


간단하죠? 역시나 진짜 간단히 짤 수 있다는 것이 고정 함수 셰이더의 최대 장점입니다.


단순히 노멀맵 텍스쳐를 하나 더 인자로 받아 적용해주고 텍스쳐 컬러 값을 적용해 준게 끝입니다.



뜨헉! 근데 이게 뭐죠! 결과가 퍼렇게 나오네요.


노멀맵 텍스쳐를 노멀맵으로 인지 하지 못해서 그냥 텍스쳐 픽셀 컬러 값으로 계산을 한 것 같습니다.


이렇게 노멀맵 텍스쳐를 쓸 때는 유니티에 얘는 노멀맵 텍스쳐라고 친절히 알려주어야 합니다.


안그러면 위와 같이 파랗게 질린 결과 화면을 보시게 될테니까요.



위처럼 텍스쳐 타입을 Normal Map으로 적용해주면, 정상적으로 범프맵이 적용됩니다.


너무 쉽지 않나요? 텍스쳐 타입을 노멀맵이라고 지정하는 것만으로 노멀맵 적용이 끝입니다!


짱짱! 노멀맵 적용 부분을 조금 더 풀어서 입력해보면 아래와 같이 해줄 수도 있습니다.


Shader "LimePapa/MyBumpedMap"

{

    ......


    SubShader

    {

        Pass

        {

            ......


            SetTexture [_BumpedTex]

            {

                ConstantColor [_DotLightDirection]

                Combine texture dot3 constant

            }


            ......

        }

    }

}


뭐 딱히 대단히 많은 코드를 더 입력한 건 아니고... 결과 값도 동일합니다.


새로 등장한 ConstantColor 키워드는 컬러 상수를 등록할 수 있는 키워드입니다.


ConstantColor를 이용해 컬러 값을 대입해주면 constant라는 상수에 해당 컬러 값이 기억됩니다.


_DotLightDirection은 유니티 고정 함수 셰이더에서 제공하는 변수 중 하나로...


노멀 벡터와 빛의 방향 벡터를 Dot 연산으로 내적한 결과 값입니다.


Diffuse 연산 공부할 때 다들 배우셨듯 코사인 그래프를 이용해서 빛의 세기를 표현할 수 있죠.


여기서도 현재 빛의 방향에 따른 빛의 세기를 구해서 상수에 등록했다고 보시면 됩니다.


빛의 밝기 값과 노멀 맵 텍스쳐의 컬러 값을 곱해서 노멀 맵을 적용해 준 것입니다.



뭐 이렇게 풀어서 적용해 주어도 어쨋든 결과는 같습니다.


그래도 그냥 넘어가는 것 보다는 알고 넘어가는게 조금은 더 낫겠죠?


오늘은 여기까지 하겠습니다! 끝!


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


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


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


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


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


이 글을 공유하기

댓글

Designed by CMSFactory.NET