04-27 14:46
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[Programming / WebGL(three.js)] CINEMA 4D로부터 Collada Export하여 WebGL에서 불러오기 본문

Programming/WebGL(ThreeJS)

[Programming / WebGL(three.js)] CINEMA 4D로부터 Collada Export하여 WebGL에서 불러오기

cinema4dr12 2016. 6. 6. 19:00

이번 글에서는 CINEMA 4D를 이용하여 지오메트리 모델을 Collada로 내보내기(export)하고 이를 three.js의 Collada importer로  불러오는 방법에 대하여 알아보기로 하겠습니다.

오브젝트 굽기(Baking Object)

Collada 포맷으로 내보낼 오브젝트를 생성 또는 로드(load)합니다. 콘텐츠 브라우저를 이용하여도 좋습니다. 예제로서 아래 이미지와 같이 비행기 모델을 열었습니다.




내보내고자 하는 모델 외에 모두 지웁니다. 그리고, 해당 프로젝트 파일을 Menu > File > Save project with Assets...로 저장합니다 (지정한 이름으로 폴더가 생성됩니다).


Scene Manager에서 모든 지오메트리를 선택하고, 우클릭하여 Connect Objects + Delete를 선택합니다.




모든 오브젝트가 하나의 오브젝트로 합쳐집니다. 이제 오브젝트를 굽도록 한다. 여기서 굽는다는 것은, 하나의 텍스쳐(UV map)로 만든다는 것입니다. 하나로 합쳐진 오브젝트를 선택하고 Scene Manager Menu > Objects > Back Object...를 선택한다.




옵션 중 Single TextureReplace Objects를 체크하고, Supersampling 값을 1로, Pixel Border는 3으로 합니다 (해당 옵션 값은 사용자가 원하는 품질에 따라 다양하게 테스트 해보길 권장드립니다).


WidthHeight는 512로 설정하였고, Format은 PNG로 하였으며, Path Name은 해당 텍스쳐 이미지를 저장할 경로이므로 각자의 환경에 맞게 설정하면 됩니다.




다음과 같이 UV map 텍스쳐가 생성되었습니다.




이제 필요없는 material은 삭제해도 좋습니다.

Collada 포맷으로 내보내기

CINEMA 4D는 두 가지 버전의 Collada 포맷 익스포터(exporter)를 제공합니다. 1.4와 1.5가 있는데, three.js Collada 임포터(importer)는 1.4를 지원하므로 1.4로 내보내기 합니다.




아래 이미지는 Collada 내보내기 옵션인데, animation이 있는 경우 animation을 체크합니다. 그러나, animation의 경우도 frame baking을 하여 내보내기해야 합니다.


내보낸 Collada 포맷(.dae) 파일을 텍스트 편집기를 이용하여 엽니다. Collada 포맷은 일종의 XML 형식으로 되어 있으므려 텍스트 편집기에서 열립니다. 내보낸 Collada 파일과 UV map 텍스쳐 파일이 동일한 폴더 내에 위치하도록 하고, 다음과 같이 수정합니다.


<?xml version="1.0"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
    <asset>
        <contributor>
            <authoring_tool>CINEMA4D 16.050 COLLADA Exporter</authoring_tool>
        </contributor>
        <created>2016-06-06T10:23:21Z</created>
        <modified>2016-06-06T10:23:21Z</modified>
        <unit meter="0.01" name="centimeter"/>
        <up_axis>Y_UP</up_axis>
    </asset>
    <library_images>
        <image id="ID3">
            <init_from>file:///D:/temp/airplaneSurface_Color.png</init_from>
        </image>
        ...


init_from 태그의 내용을 다음과 같이 수정한다.


<?xml version="1.0"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
    <asset>
        <contributor>
            <authoring_tool>CINEMA4D 16.050 COLLADA Exporter</authoring_tool>
        </contributor>
        <created>2016-06-06T10:23:21Z</created>
        <modified>2016-06-06T10:23:21Z</modified>
        <unit meter="0.01" name="centimeter"/>
        <up_axis>Y_UP</up_axis>
    </asset>
    <library_images>
        <image id="ID3">
            <init_from>./airplaneSurface_Color.png</init_from>
        </image>
        ...

Three.js Collada Importer로 불러오기

three.js 웹사이트로부터 source를 다운로드 합니다.


다운로드한 source 내의 examples 경로 내에 models/collada/ 에 CINEMA 4D에서 생성한 모델 폴더를 이동시킵니다 (이 폴더 내에 Collada 파일과 Texture 파일이 존재해야 합니다).


examples 경로에 있는 webgl_loader_collada.html 파일을 열고, loader.load() 함수의 모델 경로를 자신이 생성한 Collada 파일로 지정합니다.


1
2
3
4
5
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( './models/collada/airplane/airplane.dae', function ( collada ) {
    ...
}
cs


필요에 따라 모델의 스케일을 조정해야 하는 경우가 있을 것입니다.



dae.scale.x = dae.scale.y = dae.scale.z = any scale value you want;

Result



Source Code

webgl_loader_collada.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<!DOCTYPE html>
 
    <head>
        <title>three.js webgl - collada</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: #000000;
                margin: 0px;
                overflow: hidden;
            }
 
            #info {
                color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
 
            }
 
            a { color: skyblue }
        </style>
    </head>
     
        <script src="../build/three.min.js"></script>
 
        <script src="js/loaders/ColladaLoader.js"></script>
 
        <script src="js/Detector.js"></script>
        <script src="js/libs/stats.min.js"></script>
 
        <script>
 
            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
            var container, stats;
 
            var camera, scene, renderer, objects;
            var particleLight;
            var dae;
 
            var loader = new THREE.ColladaLoader();
            loader.options.convertUpAxis = true;
            loader.load( './models/collada/airplane/airplane.dae'function ( collada ) {
 
                dae = collada.scene;
 
                dae.traverse( function ( child ) {
 
                    if ( child instanceof THREE.SkinnedMesh ) {
 
                        var animation = new THREE.Animation( child, child.geometry.animation );
                        animation.play();
 
                    }
 
                } );
 
                dae.scale.x = dae.scale.y = dae.scale.z = 0.08;
                dae.updateMatrix();
 
                init();
                animate();
 
            } );
 
            function init() {
 
                container = document.createElement( 'div' );
                document.body.appendChild( container );
 
                camera = new THREE.PerspectiveCamera( 45window.innerWidth / window.innerHeight, 12000 );
                camera.position.set( 223 );
 
                scene = new THREE.Scene();
 
                // Grid
 
                var size = 14, step = 1;
 
                var geometry = new THREE.Geometry();
                var material = new THREE.LineBasicMaterial( { color: 0x303030 } );
 
                for ( var i = - size; i <= size; i += step ) {
 
                    geometry.vertices.push( new THREE.Vector3( - size, - 0.04, i ) );
                    geometry.vertices.push( new THREE.Vector3(   size, - 0.04, i ) );
 
                    geometry.vertices.push( new THREE.Vector3( i, - 0.04- size ) );
                    geometry.vertices.push( new THREE.Vector3( i, - 0.04,   size ) );
 
                }
 
                var line = new THREE.LineSegments( geometry, material );
                scene.add( line );
 
                // Add the COLLADA
 
                scene.add( dae );
 
                particleLight = new THREE.Mesh( new THREE.SphereGeometry( 488 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
                scene.add( particleLight );
 
                // Lights
 
                scene.add( new THREE.AmbientLight( 0xcccccc ) );
 
                var directionalLight = new THREE.DirectionalLight(/*Math.random() * 0xffffff*/0xeeeeee );
                directionalLight.position.x = Math.random() - 0.5;
                directionalLight.position.y = Math.random() - 0.5;
                directionalLight.position.z = Math.random() - 0.5;
                directionalLight.position.normalize();
                scene.add( directionalLight );
 
                var pointLight = new THREE.PointLight( 0xffffff1 );
                particleLight.add( pointLight );
 
                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );
 
                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );
 
                //
 
                window.addEventListener'resize', onWindowResize, false );
 
            }
 
            function onWindowResize() {
 
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
 
                renderer.setSize( window.innerWidth, window.innerHeight );
 
            }
 
            function animate() {
 
                requestAnimationFrame( animate );
 
                render();
                stats.update();
 
            }
 
            var clock = new THREE.Clock();
 
            function render() {
 
                var timer = Date.now() * 0.0005;
 
                camera.position.x = Math.cos( timer ) * 10;
                camera.position.y = 2;
                camera.position.z = Math.sin( timer ) * 10;
 
                camera.lookAt( scene.position );
 
                particleLight.position.x = Math.sin( timer * 4 ) * 3009;
                particleLight.position.y = Math.cos( timer * 5 ) * 4000;
                particleLight.position.z = Math.cos( timer * 4 ) * 3009;
 
                THREE.AnimationHandler.update( clock.getDelta() );
 
                renderer.render( scene, camera );
 
            }
 
        </script>
cs


'Programming > WebGL(ThreeJS)' 카테고리의 다른 글

[Programming / WebGL] Web Cam Texture  (0) 2016.08.28
[WebGL/ThreeJS] COLLADA(dae) Loader  (0) 2015.10.11
[WebGL] Path Tracing  (0) 2015.08.07
[WebGL] Blur Shader  (0) 2015.08.07
[WebGL] Bloom Shader  (0) 2015.08.07
Comments