본문 바로가기
공허의 유산/표현의 자유

[Unity3D/Shader] 01. 기본 환경 준비

by 바른생활머시마 2023. 2. 16.
728x90
반응형

최근에 GLSL에 대해 리뷰를 해왔습니다.

https://learn-and-give.tistory.com/12

 

[opengl].[#2.GLSL] 01. OpenGL 1.1 기반의 랜더링

최신의 OpenGL과 Shader를 사용하기 위해 glew 연동까지 준비가 되었습니다. 1. 기본 랜더링 코드 이후에 진행 될 GLSL 기반의 랜더링과 비교를 용이하게 하기 위해, 1.1 기반의 랜더링에 조금 신경을 써

learn-and-give.tistory.com

 

기본 환경을 만드는 것도 꽤 번거로운 일이었고, 요즘에 OpenGL로 직접 application을 만드는 경우가 매우 제한 된 경우에만 있다보니 배워서 쓸 곳도 많이 않은 것 같고.ㅋㅋ...ㅠ_ㅠ... 새로 나오는 언어들의 3D 기능들도 좋아지고...뭐 여러가지 환경적인 조건이 opengl이나 glsl을 직접 환경을 갖춰서 할 일은 점점 드물어지는 것 같아요. 하지만, 공부를 하고서 다른 환경을 살펴보면 분명 이해하는데 매우 큰 도움이 됩니다. 그리고, 속도도 훨씬 빠르고~ 그러니 필수는 아니라도 배워두면 매우 큰 도움이 되는 것은 분명합니다.

 

3D application을 OpenGL로 직접 처음부터 만드는 경우는 많지 않을 것 같은데, 20여년 전 쯤에는 매우 흔한 경우였고, 게임엔진을 써서 application을 만드는 것이 조금 드물었던 것 같아요. 비용적인 문제도 있고, OpenGL 커뮤니티도 활발했던 것 같아요.

 

세상은 변했고, 이제 게임엔진이 단지 게임에만 쓰이지 않고, 영화에도 쓰이고, 게임은 물론이고 엔지니어링과 시뮬레이션 등 3D와 관련 된 다양한 application을 만드는 효율적인 툴로 쓰이고 있습니다. 대표적인 게임엔진 중 하나인 유니티3D에서도 쉐이더를 할 수 있는데, 환경 구축은 간단히 되기 때문에 좀 더 쉐이더 자체에 집중 할 수 있고, 그 결과를 application에 활용 할 수 있다는 장점도 있죠.

 

이번 리뷰는 필명 '대마왕'을 쓰시는 '정종필'님께서 쓰신 책을 바탕으로 제 경험과 실험을 더 보태어 가면서 쓰겠습니다.

https://product.kyobobook.co.kr/detail/S000001888115 

 

유니티 쉐이더 스타트업 | 정종필(대마왕) - 교보문고

유니티 쉐이더 스타트업 | 『유니티 쉐이더 스타트업』은 프로그래밍으로 완성해야 하는 쉐이더의 구현을 아티스트들의 역량으로도 충분히 발휘할 수 있도록 도움을 주는 책입니다. 저자의 오

product.kyobobook.co.kr

이 책은 개발자가 아닌 디자이너들을 위해 쓰인 책인데요, 그러다보니 매우 쉽게 설명하는데 많은 정성을 쏟으셨어요. 책을 읽다보면 그렇게 마음을 쓰신 흔적들이 많이 보여서 참 감사한 마음이 듭니다. 책에도 언급 된 내용입니다만, 저와 같은 쉐이더 입문 개발자들에게도 매우 도움이 되는 책인 것 같아요.

 

 

 

HLSL v.s. GLSL v.s. Cg

 

세 개의 쉐이더 언어가 있는데, Cg는 Nvidia에서 만들었고, HLSL은 MS에서(DirectX의 짝꿍으로) 만들었고, GLSL은 OpenGL의 짝꿍으로 크로노스 그룹(의 OpenGL ARB?)에서 만들었습니다. 다 비슷비슷하죠. Unity3D의 쉐이더에서는 HLSL을 쓰는데 Cg와도 거의 비슷해요(Cg는 Nvidia가 MS랑 같이 만들어서...). (*생성 된 쉐이더 코드의 주석에는 CG라고 되어 있네요.) Unity에서 GLSL도 쓸 수 있지만 권장되지 않는다네요.

https://ko.wikipedia.org/wiki/%EA%B3%A0%EA%B8%89_%EC%85%B0%EC%9D%B4%EB%8D%94_%EC%96%B8%EC%96%B4

 

고급 셰이더 언어 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 고급 셰이더 언어(High Level Shader Language)는 마이크로소프트의 다이렉트3D API에 사용되는 셰이딩 언어이다. 고급 셰이딩 언어(High Level Shading Language)라고도 불리며

ko.wikipedia.org

https://ko.wikipedia.org/wiki/Cg_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4) 

 

Cg (프로그래밍 언어) - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. -->

ko.wikipedia.org

 

같은 하드웨어 위에서 돌아가야 하니까 결국 비슷 할 수 밖에 없을 것입니다. 더군다나 성능을 위해 최적화를 해야 하니 별로 다르게 갈 만한 선택의 여지가 별로 없을 것입니다. 

 

 

Unity Shader

 

Unity 매뉴얼에도 쉐이더 부분이 있는데, 처음부터 이걸 보면서 공부하기는 좀 쉽지 않은 것 같아요. 그래서, 저 위에 소개한 책을 한번 보면 훨씬 도움이 될 것 같습니다.

https://docs.unity3d.com/kr/current/Manual/Shaders.html

 

셰이더 - Unity 매뉴얼

이 섹션은 Unity에서 셰이더를 사용하여 작업하는 방법을 설명합니다.

docs.unity3d.com

 

지원되는 쉐이더는 3가지 종류가 있는데, 아래 내용이 참고가 됩니다.  

쉐이더의 능력을 잘 보여주지 못하는 고정파이프라인 쉐이더가 있고, GLSL 공부 할 때 배운 것 처럼 Vertex Shader/ Fragment Shader를 직접 작성하는 경우도 있고, Surface shader라는 것도 있다고 합니다. 말하자면 Unity 환경에서 좀 더 쉽게 쓸 수 있도록 준비한 유니티 전용 쉐이더랄까.... 하지만, 그 속에 쉐이더 코드가 차지하는 부분과 Unity 환경을 연결해주는 부분이 있다보니, 뭐 그냥 쉐이더라고 봐도 될 것 같아요.

https://docs.unity3d.com/kr/current/Manual/SL-ShadingLanguage.html

 

셰이더 작성 개요 - Unity 매뉴얼

Unity용 셰이더를 작성할 때는 다음 언어를 사용합니다.

docs.unity3d.com

 

 

 

 

Unity 준비

 

자, 이제 Unity에서 한번 해보도록 하겠습니다. 

이렇게 뭔가 새롭게 시작 할 때, 사용하는 툴들을 한번 업데이트 해주면 좋겠네요. @_@

UnityHub도 업데이트 하고~

오래 된 Editor는 삭제하고~

새 버젼도 설치하고~

 

앱을 설치 할 것은 아니라서 실행 플랫폼용 모듈은 따로 설치 하지 않아도 될 것 같은데, 혹시 웹으로 해보고 싶을지도 모르니 WebGL만 추가 해 두겠습니다.

3D 환경에서 해보는걸로~

 

반응형

 

 

Scene 준비

 

Unity 프로젝트가 준비 되었으면, 책 내용처럼 구를 하나 추가합니다. GLSL 공부 할 때도 구를 가지고 했었죠?

하얀색 구가 생겼습니다.

Unity에서 표면을 꾸며주는 방법은 재질(Material)을 적용하는 것인데, 그런 내용을 자세하게 다룰 수는 없고, 재질을 정의하고, 그 재질은 다양한 종류의 데이터를 이용해서 표현을 할 수 있으며, 이미지도 재질에서 사용 할 수 있고, 쉐이더도 재질에서 사용할 수 있고 등등.... 표면을 꾸밀 수 있는 다양한 재료를 묶어주는 상위 오브젝트 정도로 정리하고 넘어가겠습니다.

  화면 아래쪽 Project 폴더들이 보이는 곳에서 적당한 곳(Asset 폴더 위치도 좋고)에서 context menu를 이용하여 Material을 추가합니다.

같은 곳에 Standard Surface Shader도 하나 추가 합니다.

Shader를 선택하고 오른쪽에 보이는 속성들을 보면, 쉐이더 부분에 다양한 쉐이더를 선택 할 수 있는 UI가 있습니다. 여러 환경이나 조건에 따라 사용 할 법한 쉐이더를 제공해 주고 있는데, 매우 다양하기 때문에 잘 선택해서 쓰면 직접 만들어서 쓰지 않아도 됩니다. 오브젝트를 만들면 기본적으로 Standard Shader가 할당되어 있습니다.

 

그 Standard Shader를 선택해보면, 지금은 뭔지 모를 많은 내용들이 있습니다. 그냥 모르는 상태로 둡시다.ㅋ

 

Custom Shader

앞에서 Project 폴더 내에 생성한 쉐이더를 선택하고 Inspector를 보면, 내가 따로 이름을 붙이거나 어디 폴더에 넣은 것이 아닌데, Custom이라는 구분이 되어 있습니다. 요거 기억해두고~  아래쪽에 보이는 Property가 아까 앞에서 본 Standard Surface Shader보다 훨씬 적습니다.

 새로 추가한 쉐이더를 새로 추가한 재질에 적용하기 위해서는 새 쉐이더를 Drag하여 왼쪽의 재질에서 Drop을 하거나, 재질을 선택한 상태에서 Inspector에 보이는 Shader 자리에 Drop하면 됩니다.

 

 

 

Shader 편집

이제 쉐이더 편집을 해야 하는데, Shader를 더블클릭하면 됩니다. 따로 연결 된 프로그램이 없으면, 그냥 텍스트 편집기로 하면 됩니다. 저는 연결 프로그램에서 VSCode를 선택 해 보겠습니다.

 

 편집기가 열리면, 아까 Unity Inspector에서 봤던 내용들이 보이는데, Custom으로 시작하는 이름이 여기에 적혀있고, Property도 Inspector에서 봤던 그대로 있습니다.

Unity에서 Shader를 선택하고 Inspector를 다시 확인 해 보면 서로 연결 되어 있다는 것을 알 수 있습니다.

Inspector에 보이는 항목 중, Show generated code를 누르면 다른 코드가 하나 뜨는데, 매우 긴 코드 입니다. 이것으로 유추해 보자면, 사용자가 작성하는 Shader는 추상적인 혹은 의도만 담는 것이고, 이를 실제 플랫폼에서 돌아가는 코드로 빌드 해 주는 것 같습니다.

 

생성 된 쉐이더 코드 말고, 원래 쉐이더 코드를 아래와 같이 수정 합니다. 

4개의 Property를 Unity Editor로부터 전달 받고, (이 값을 쓰지는 않고...)

surf라는 함수에 뭔가 구현이 되어 있는데, 출력 될 변수의 알베도에 빨간색을 설정합니다.

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = float3(1,0,0);
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

자, 이제 한가지 빼고 준비가 다 되었습니다. 이렇게 준비 된 재질을 오브젝트에 적용하려면, 재질을 오브젝트에 Drag & Drop하면 됩니다. 아까는 Shader를 Material에 Drag & Drop, 이번에는 그 Material을 오브젝트에 Drag & Drop.

 

OpenGL와 GLSL을 사용 할 수 있는 환경 구축의 번거로움 없이, 간편하게 쉐이더를 사용 할 수 있는 환경을 만들었습니다. 물론, Unity에 익숙하지 않은 사람에게는 이후의 진행이 쉽지 않겠지만, 쉐이더의 활용까지 고려한다면 게임엔진에서 해보는 것이 좋은 것 같아요. 특히, Property를 통해서 Unity Editor와 연동하는 변수가 있기 때문에, Runtime에 값을 바꾸고 그 값을 Shader에 전달 할 수 있는 간편한 방법이 있다는 뜻입니다. GLSL 공부 할 때 uniform 변수를 쓰기 위한 몇 가지 준비의 번거로움을 하지 않아도 되죠. 더군다나 그 값을 GUI로 조정 할 수 있다면 실험/테스트 할 때 매우 편리 할 것 같습니다.

728x90
반응형

댓글