쉐이더 시스템의 통합 : Nebula2와 3ds Max

@ 이 글은 ShaderX5에 기고했던 글을 한글로 번역한 것입니다. 글과 관련된 소프트웨어의 모든 저작권은 저에게 있음을 밝힙니다.



쉐이더 시스템의 통합 : Nebula2 3ds Max

김 현 우

 



서론


      이 글에서는 아티스트가 손쉽게 쉐이더 파라미터를 조작할 수 있도록 쉐이더 시스템을 DCC(Digital Contents Creation)툴에 통합하는 아이디어를 Nebula2 엔진의 3ds Max 플러그인 툴인
nmaxtoolbox를 통해서 설명한다. The Nebula2 Device[Nebula06] C++로 작성된 3D 게임 및 시각화를 위한 3차원 엔진이다. Nebula 엔진의 두 번째 버전인 Nebula2는 렌더링 엔진에 쉐이더를 사용하고 있는데 이러한 특징 때문에 3D 작업 파이프라인에도 쉐이더 중심의 시스템이 필요하다.

 

여기에서 설명할 시스템은 프로그래머와 아티스트 모두가 고려해야 할 것으로 다음과 같은 장점을 가진다.

l       DCC 툴에 쉽게 통합할 수 있으며 변경이 용이하다.

l       작성하기 쉬우며 기존의 코드 베이스에도 쉽게 통합할 수 있다.

l       아티스트가 조작하는 DCC 툴의 쉐이더 UI를 위해서 이미 작성된 쉐이더 코드를 수정할 필요가 없다.

l       쉐이더 코드에 독립적이다. 쉐이더 코드는 임의의 쉐이더 랭귀지로 작성할 수 있으며 랭귀지와 무관하게 쉐이더 파라미터를 변경하고 프리뷰할 수 있는 방법을 제공한다.

l       쉐이더 파라미터 조작을 위한 UI를 손쉽게 작성할 수 있는 방법을 보여준다.

l       변경된 쉐이더 파라미터에 대한 피드백을 DCC 툴 내에서 사용자에게 즉각적으로 보여준다.

l       DCC 툴의 SDK를 사용하지 않고 DCC 툴에 통합한다.(시스템의 구현이 간단해서 빠르게 구현하는 것이 가능하다)

 



Art Pipeline
통합


      아티스트가 그들이 만든 작업물을 의도한 대로 보이도록 해서 최종적인 그래픽의 품질을 높일 수 있도록 하기 위해서는 3차원 그래픽 툴에서 아티스트가 손쉽게 쉐이더 파라미터를 변경할 수 있는 방법을 제공하는 것이 중요하다. 이러한 이유로 근래의 DCC 툴에서는 쉐이더의 지원과 함께 이와 같은 시스템을 제공하고 있다.

이러한 예로 3ds Max 6 이후 버전에서는 이펙트 파일의 HLSL 쉐이더 파라미터를 노출 시키는 것이 가능하다. 3ds Max로 로딩된 이펙트 파일은 이펙트 파일 내의 상응하는 DXSAS[DXSAS01]를 분석해서 아티스트가 쉐이더 파라미터를 조작할 수 있는 UI 컨트롤을 머티리얼 에디터에서 제공한다. 이 방법은 매우 유용한 방법이긴 하지만 DXSAS 포맷의 쉐이더에 국한된다는 단점이 있다.

 

nmaxtoolbox에서는 아래 그림 1에서처럼 3ds Max에서 기본적으로 제공하는 시스템과는 다른 작업 흐름을 사용한다.


그림 1. Nebula2 3ds Max 툴킷 작업 흐름

 

위의 다이어그램에서 보면 프로그래머가 작성한 이펙트 파일들은 미리 지정된 위치로 복사되며 게임 엔진에서는 이 위치를 알고 있다. 다음으로 3차원 그래픽 툴의 플러그인(nmaxtoolbox)에서는 특정 쉐이더의 쉐이더 파라미터를 변경하기 위한 UI 컨트롤을 동적으로 생성한다. UI 컨트롤 생성을 위한 정보는 ‘shaderx.xml’파일로부터 파싱되어 얻어 진다. 마지막으로 게임 엔진에서는 ‘renderpath.xml’파일에서 렌더링에 필요한 쉐이더 코드에 대한 정보를 얻어 온다.

 

아티스트의 요구 사항을 만족시키기 위해서 플로그인에서는 다음의 두 가지를 제공해야 한다.

l       손쉽게 쉐이더 파라미터를 조작할 수 있는 사용자 인터페이스

l       변경된 쉐이더 파라미터 정보에 대한 실시간 피드백

 

3ds Max에서 쉐이더 파라미터 조작을 위한 사용자 인터페이스를 만드는 가장 손쉬운 방법 중의 하나는 3ds Max에서 제공하는 스크립트 언어 도구인 MAXScript를 이용하는 것이다.

nmaxtoolbox에서는 개별 쉐이더의 파라미터들에 대한 정보가 XML 메타 파일인 ‘shaders.xml’파일에 저장된다. 메타 파일에서는 파라미터의 이름, (type) 그리고 기본값과 플러그인에서 UI 컨트롤 생성을 위해서 필요한 부가적인 정보를 가지고 있다.

3ds Max가 실행될 때 플러그인에서는 주어진 메타 파일을 사용해서 자동으로 쉐이더 파라미터 조작을 위한 UI 컨트롤의 MAXScript 코드를 생성하게 된다.

 

다음은 shaders.xml메타 파일의 일부분이다.

 

    <shader name="Standard" shaderType="default" meshType="default bsp" file="static">

        ...

        <param name="MatDiffuse" label="Diffuse Color" type="Color" gui="1" export="1" def="1.0 1.0 1.0 1.0" />

        <param name="MatEmissive" label="Emissive Color" type="Color" gui="1" export="1" def="0.0 0.0 0.0 0.0" />

        <param name="MatEmissiveIntensity" label="Emissive Intensity" type="Float" gui="1" export="1" min="0.0" max="10.0" def="1.0" />

        <param name="MatSpecular" label="Specular Color" type="Color" gui="1" export="1" def="0.5 0.5 0.5 1.0" />

        ...

    </shader>

 

위의 메타 파일은 Standard’라는 쉐이더 조작에 사용되는 UI 컨트롤에 대한 정보를 가지고 있다. 첫 번째 쉐이더 파라미터는 컨트롤 이름으로  MatDiffuse를 사용하며 Diffuse Color를 레벨로 가지며, 타입(type) Color UI 컨트롤로 3ds Max color picker 컨트롤을 사용한다는 것을 의미한다. def Default Value를 의미하는 것으로, UI 컨트롤 생성시 color picker 은 기본값으로 RGBA(1.0, 1.0, 1,0, 1.0)를 사용하게 된다. 그림 2‘Standard’쉐이더를 위해서 생성된 사용자 인터페이스를 보여 주고 있다.

 

그림 2. 3ds Max 머티리얼 에디터 내의 Nebula2 쉐이더 UI 컨트롤

 

위의 방법의 장점은 작성된 쉐이더 랭귀지에 관계 없이 CgFXHLSL혹은 다른 어떠한 쉐이더 랭귀지를 사용하던지 간에 쉐이더 랭귀지와 무관하게 쉐이더 파라미터들에 대한 UI 컨트롤을 제공할 수 있다는 것이다.

또 다른 장점은 동일한 쉐이더 UI 메타 파일을 다른 3차원 그래픽 툴에서도 사용할 수 있다는 것이다.

그런데, MAXScript를 사용해서 UI 컨트롤을 추가하는 일이 쉬운 일이긴 하지만 프로그래머가 새로운 쉐이더 코드를 작성할 때마다 작성된 쉐이더의 쉐이더 파라미터를 조작하는데 필요한 UI 컨트롤의 MAXScript 코드를 새로 작성하는 일은 비효율적이다. 그래서 플러그인에서는 UI 컨트롤을 생성하는데 필요한 MAXScript 코드를 메타 파일로부터 자동으로 생성하는 로직을 탑재하고 스핀 컨트롤, 드롭 다운 리스트 컨트롤, 텍스쳐 버튼, 컬러 픽커와 같은 컨트롤들을 위한 스크립트 코드를 자동으로 생성하는 방법을 사용한다.

 

대부분의 3차원 그래픽 툴에서는 스크립팅 언어 도구를 제공하고 있으므로 이러한 그래픽스 툴의 스크립팅 엔진을 이용하면 필요한 UI 컨트롤을 손쉽게 만들 수 있다. 만약 사용하는 그래픽스 툴에서 이러한 스크립팅 엔진을 제공하지 않는 경우에는 UI 컨트롤을 위한 C++ 코드를 자동으로 생성하는 방법으로 스크립팅 언어를 사용하는 것과 비슷하게 구현할 수도 있다.

 

그림 3. Neulba2 Maya 머티리얼 에디터

 

그림 4. Nebula2 LightWave 머티리얼 에디터

 

Maya 툴의 Nebula2 플러그인에서는 MEL(Maya의 스크립팅 언어)을 사용해서 쉐이더 파라미터의 UI 컨트롤을 생성했다.[NebulaMayaToolkit06] 이와는 달리 LightWave에서는 C++ 코드를 생성해서 동일한 방법을 제공하고 있다.

요약하자면 쉐이더 메타 파일에 새로운 쉐이더 엔트리를 삽입하고 쉐이더 파라미터들을 설정하면 플러그인에서는 3D 그래픽스 툴에서 필요한 UI 컨트롤들을 생성하는데 필요한 스크립트(혹은 C++ 코드)를 자동으로 생성한다는 것이다. 이러한 작업 과정의 특징은 변경을 이해하는 것이 매우 쉽기 때문에 아티스트가 3D 그래픽스 툴의 스크립팅 언어에 익숙하지 않아도 작업 할 수 있는 것이 장점이다.

 

다음은 Standard쉐이더의 쉐이더 파라미터 UI 컨트롤을 위해서 생성된 MAXScript코드이다.

 

 

    caStandard = attributes "Standard"

    (

    parameters Standard rollout:rStandard

    (

        ...

        MatDiffuse type:#frgba default:[255.000000, 255.000000, 255.000000, 255.000000] ui:MatDiffuse

        on MatDiffuse set val do

        (

            if loading != true do

            (

                curMaterial = medit.GetCurMtl()

                if classof curMaterial != MultiMaterial do

                    if curMaterial.delegate != undefined do

                       curMaterial.delegate.ambient = val

            )

        )

        ...

 

        rollout rStandard "Standard Parameters"

        (

            ...

            colorpicker MatDiffuse "Diffuse Color" align:#left alpha:true color:[255.000000, 255.000000, 255.000000, 255.000000]

            colorpicker MatEmissive "Emissive Color" align:#left alpha:true color:[0.000000, 0.000000, 0.000000, 0.000000]

            ...

        )

    )

 



데이터 교환


    아티스트가 조작해서 변경한 쉐이더 파라미터들의 값은 3D 모델이 익스포트될 때 플러그인에서 해당 값을 읽어 들여서 같이 익스포트할 수 있어야 한다. 3ds Max에서는 custom attribute 를 사용해서 이와 같이 작업할 수 있으며 Maya에서는 extra attributes 로 쉐이더 파라미터의 값을 읽고 저장할 수 있다. 이들은 3D 모델이 scene 파일에 저장될 때 함께 사용자가 임의로 생성해서 같이 저장할 수 있는 부가적인 정보이다.

 

플러그인에서는 쉐이더에 대한 별칭만을 익스포트하며 쉐이더 코드 자체를 익스포트하지 않는다는 사실에 주목하자. 플러그인에서 참조한 쉐이더의 별칭을 실제 이펙트 파일에 매칭하는 것은 렌더링 엔진에서 사용하는 renderpath.xml메타 파일에 정의되어 있다. 다음은 renderpath.xml메타 파일의 일부분이다.

 

    <RenderPath name="dx9hdr" shaderPath="home:data/shaders/2.0">

        ...

        <!-- declare shaders and technique aliases -->

        <Shader name="passes" file="shaders:passes.fx" />

        <Shader name="phases" file="shaders:phases.fx" />

        <Shader name="compose" file="shaders:hdr.fx" />

        <Shader name="static" file="shaders:shaders.fx" />

        <Shader name="static_atest" file="shaders:shaders.fx" />

        <Shader name="environment" file="shaders:shaders.fx" />

        <Shader name="lightmapped" file="shaders:shaders.fx" />

        <Shader name="lightmapped2" file="shaders:shaders.fx" />

        <Shader name="radiosity_normalmapped" file="shaders:shaders.fx" />

        <Shader name="skinned" file="shaders:shaders.fx" />

        <Shader name="blended" file="shaders:shaders.fx" />

        <Shader name="alpha" file="shaders:shaders.fx" />

        ...

    </RenderPath>

 

예를 들어 익스포트된 모델의 쉐이더 별칭이 ‘static’인 경우 렌더링 엔진에서 해당 모델을 렌더링할 때 ‘shaders.fx’이펙트 파일의 쉐이더 코드를 사용하게 된다.

 

다음은 Nebula2의 모델을 생성하는 Nebula Tcl스크립트의 예이다.

 

    new nshapenode model_0

    sel model_0

    .settexture "DiffMap0" "textures:materials/checker.dds"

    .settexture "BumpMap0" "textures:materials/bump.dds"

    .setvector "MatDiffuse" 1.000000 1.000000 1.000000 1.000000

    .setvector "MatEmissive" 0.000000 0.000000 0.000000 0.000000

    .setfloat "MatEmissiveIntensity" 1.000000

    .setvector "MatSpecular" 1.000000 1.000000 1.000000 1.000000

    .setfloat "MatSpecularPower" 18.160000

    .setint "CullMode" 2

    .setfloat "BumpScale" 0.000000

    .setshader "static"

    .setgroupindex 0

    sel ..

 

위의 스크립트에서 렌더링시 모델에 사용할 텍스쳐 파일과 diffuse, emissive specular광의 색상값 등이 쉐이더의 파라미터로 설정되고 있는 것을 볼 수 있다. 또한 shaders.fx이펙트 파일(renderpath.xml파일에 설정되어 있다)에 정의되어 있는 static쉐이더를 렌더링시 쉐이더로 사용하고 있다는 것도 알 수 있다.

 



실시간 피드백


    수정 및 변경된 쉐이더 파라미터에 대한 피드백을 바로 확인할 수 있는 시스템은 아티스트의 생산성을 높이기 위한 필수적인 일들 중 하나이다. 이 방법중의 하나로는 아티스트가 작업하는 3D 그래픽 툴의 뷰 내에서 변경된 쉐이더 파라미터의 효과를 바로 확인할 수 있도록 하는 것이다[
Bahnassi05]. 그러나 이 방법은 3D 그래픽 툴의 SDK를 이용해서 구현해야 하며 많은 작업 시간을 필요로 하는 일이다.

nmaxtoolbox에서는 익스포트되는 컨텐츠는 디스크에 미리 지정된 위치로 익스포트 되며 별도의 프리뷰어를 제공해서 익스포트된 컨텐츠를 확인할 수 있도록 하고 있다.

이 방법을 3ds Max의 하드웨어 플러그인(DirectX9 Material) 구현과 비교하면 모델의 위상이 변경된 경우에 대해서는 실시간 피드백을 제공하지 않지만 두 방법 모두 3ds Max의 머티리얼 에디터에서 쉐이더 파라미터에 대한 값을 변경하는 경우에는 실시간으로 변경을 확인할 수 있다. nmaxtoolbox에서는 3ds Max의 쉐이더 파라미터에 parameter blocks을 사용하고 있으므로 scene을 저장하는 경우에 쉐이더 파라미터들도 자동으로 .max 파일에 저장된다.

 

그림 5. Nebula2 프리뷰 윈도우에서 익스포트된 모델을 렌더링하는 그림(Opelblitz 모델은 RadonLabs의 허락하에 사용함)

 

위의 그림 5에 볼 수 있듯이 아티스트는 3ds Maxcolor picker를 사용해서  모델의 diffuse 색상을 변경할 수도 있다. 변경된 내용은 바로 프리뷰 윈도우로 전달되어 프리뷰에서 확인할 수 있다.

프리뷰 윈도우는 3ds Max와 독립된 별개의 프로세스이며 nmaxtoolbox에서는 Inter-Porcess Communication(or IPC)을 사용해서 변경된 쉐이더 파라미터 값을 프리뷰 윈도우에 알린다. 결과물이 익스포트 되면 플러그인에서는 프리뷰 윈도우를 실행시키고 변경된 쉐이더 파라미터 값을 전달할 수 있도록 IPC를 이용해서 플러그인과 프리뷰 윈도우를 연결한다. 이러한 IPC 메커니즘은 TCP를 사용해서 구현되었다. 3ds Max에서 파라미터를 변경하면 MAXScript를 통해서 해당하는 파라미터 변경에 대한 Nebula2 스크립트가 프리뷰 윈도우로 전달되고 프리뷰 윈도우에서는 Nebula 엔진의 스크립트 엔진을 사용해서 전달된 스크립트를 실행하여 값을 변경하게 된다. 다음은 설명한 MAXScript코드의 한 예이다.

 

    if nIsConnectedIpc() do

    (

        nChangeShaderParameter "Standard" "common" "MatDiffuse" "0.5 1.0 1.0 1.0"

    )

 

nChangeShaderParameter스크립트 함수는 3ds Max script-callable 함수로 함수 내에서 주어진 Nebula2 스크립트를 연결된 프리뷰 윈도우로 보내는 Nebula2 API를 호출한다. 위의 코드에서 첫 번째 인자인 Standard’는 전달할 쉐이더의 타입이며, 세 번째 인자는 MatDiffuse’은 변경할 쉐이더 파라미터를 설정한다. 마지막 인자는 실제 변경할 diffuse 의 색상값이다.



 

구현


      Nebula2
엔진과
nmaxtoolbox플러그인의 소스 코드는 상업적 및 비상업적 용도 어느 경우에도 자유롭게 사용할 수 있다.[Nebula06]

 

지금까지 이 글에서는 3ds Max의 쉐이더 시스템 통합에 대해서만 이야기했지만 언급된 내용은 MayaSoftimage, LightWave와 같은 다른 3D 그래픽스 툴에서도 사용할 수 있다. 실제로 nmaxtoolbox에서 사용하는 UI 메타 파일은 RadonLabs의 상업용 마야 플러그인인 Nebula2 Toolkit for MayaNebula2 LightWave 플러그인에서도 동일하게 사용하고 있다. 게다가 이 방법은 기존의 툴 체인에도 쉽게 통합할 수 있다.

 

언급한 방법의 한가지 문제점은 각기 다른 쉐이더를 사용하고 있는 복수개의 모델로 구성된 복잡한 장면에 대한 프리뷰 윈도우를 제공하기가 어렵다는 것이다.

Python이나 Lua와 같은 다른 써드 파티 스크립트 언어를 이용해서 주어진메타 파일로부터 쉐이더 파라미터를 위한 UI 컨트롤의 MAXScript코드를 생성하는 방법을 고려할 수도 있다. 현재 nmaxtoolbox에서는 UI 컨트롤 생성을 위한 코드가 플러그인의 C++ 코드로 작성되어 있으므로 해당 코드에 대한 변경 사항이 발생할 때마다 수정 후 다시 빌드해서 3ds Max를 다시 시작해야 하는 단점이 있다. 써드 파티 스크립트를 사용해서 MAXScript코드를 생성하는 경우에는 써드 파티 스크립트의 수정만으로 UI 컨트롤 생성에 필요한 코드를 변경할 수 있으므로 플러그인을 다시 빌드할 필요가 없게 된다.

 



결론


      이 글에서는 DCC 툴 안에 게임 엔진의 시각화 도구를 통합하는 방법에 대해서 소개했다. 적은 양의 코딩만으로도 훌륭한 시스템을 통합할 수 있다는 것을
Nebula2 엔진과 nmaxtoolbox 3ds Max 플러그인을 예로 들어 설명했다.

이 시스템은 특정 쉐이더 언어에 국한되지 않으며 3ds Max가 실행할 때 플러그인이 쉐이더 파라미터들을 정의한 메타 파일을 파싱해서 MAXScript 코드를 자동으로 생성하여 3ds Max 머티리얼 에디터 내에서 쉐이더 파라미터 변경에 필요한 UI 컨트롤을 아티스트에게 제공한다.

그리고 3ds Max에서 3D 오브젝트 모델을 익스포트하면 프리뷰 윈도우가 런칭되며 익스포트된 모델은 자동으로 프리뷰 윈도우로 로딩되어 보여지게 된다. 이 윈도우는 3ds Max의 플러그인과 연결되어 사용자가 3ds Max에서 쉐이더 파라미터를 변경할 때마다 변경한 결과를 바로 프리뷰 윈도우에서도 확인할 수 있도록 한다.

 



감사의 말


      먼저 The Nebula Device라는 훌륭한 오픈 소스 3D 엔진을 공개한 RadonLabs에 감사의 뜻을 전한다. 그리고 이 글을 쓰는데 도움을 아끼지 않은 The Nebula2 LightWave Toolkit의 저자인
Vadim Macagon에게도 다시 한번 지면을 빌어 감사를 표하는 바이다.

 



참고 자료


[
Nebula06] The Nebula Device, available online at http://www.nebuladevice.org.

[DXSAS01] DirectX Standard Annotations and Semantics Reference, DirectX 9 SDK Documentation, Microsoft Corp., 2006.

[NebulaMayaTookit06] Nebula2 Toolkit 2.0 for Maya®, available online at http://www.radonlabs.de/toolkit.html.

[Bahnassi05] Homam Bahnassi and Wessam Bahnassi, Shader Visualization Systems for the Art Pipeline, ShaderX3: Advanced Rendering with DirectX and OpenGL, Wolfgang Engel, ed., Charles River Media, 2005, pp. 487-504.

 

by kimsama | 2007/10/03 13:52 | Nebula Device | 트랙백(1) | 핑백(4) | 덧글(6)

트랙백 주소 : http://kimsama.egloos.com/tb/1645106
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from CrazyXIII at 2007/10/10 19:12

제목 : 쉐이더 시스템의 통합 : Nebula2와 3ds Max
쉐이더 시스템의 통합 : Nebula2와 3ds Max 맥스 스크립트 강좌...more

Linked at ahastudio님의 글 - .. at 2007/10/16 19:24

... 0 metoo 쉐이더 시스템의 통합 : Nebula2와 3ds Max이 올라왔다. 요새는 Material을 별도로 분리하는 방식으로 돌아갔지만, 맥스 안에서 이것저것 다 하는 건 여전히 매혹적이다. ... more

Linked at East Agent's Blo.. at 2007/11/11 14:45

... KGC2007쉐이더 시스템 통합: Nebula2 &amp; 3ds Max - http://kimsama.egloos.com/1645106 ... more

Linked at East Agent's Blo.. at 2008/10/04 15:05

... 된 포스트들만으로는 쉽게 잘 이해가 되지 않거나 실제 사용에 대한 예를 보기를 원한다면 Nebula3의 코드를 찬찬히 보기를 바랍니다. 또 지난 포스트 중에 "쉐이더 시스템의 통합: Nebula2와 3DS Max"도 한번 보시길. ^^ ... more

Linked at East Agent's Blo.. at 2008/11/15 12:02

... UI 코드는 작성하지 않고 데이터 타입에 따라서 자동으로 UI 코드를 생성하여 인터페이스를 제공하는 것이 핵심입니다. Reflection은 아닙니다만 이전에 "쉐이더 시스템의 통합: Nebula2와 3ds Max"에서도 UI 코드의 자동 생성의 이점과 필요성에 대해서는 한번 언급한 적이 있습니다. 게임 개발에 국한 한다면, Reflection을 잘 이용하면 GU ... more

Commented by kimsama at 2007/10/03 14:11
ShaderX5에 기고한 글입니다.
Commented by kimsama at 2007/10/03 14:12
원문은 책을 구입하시길~ ^^;
Commented by 김윤정 at 2007/10/03 21:01
호오... 이 내용이셨군요 .... 우후후후.
언젠가는 쉐이더 코드가 표준화되고, 맥스에 정식 탑재될 지도 모르겠네요 ...
잘 보고 갑니다 ^^
Commented by cagetu at 2007/10/10 19:13
좋은 내용 보고 갑니다.. 무단 트랙백걸었는데 괜찮으실런지.. ㅡㅡ
Commented by kimsama at 2007/10/11 23:27
트랙백을 밝히셨으니 무단은 아니시죠 ^^;
Commented at 2007/10/18 18:13
비공개 덧글입니다.

:         :

:

비공개 덧글

◀ 이전 페이지다음 페이지 ▶