그림으로 나타내기 위한 정보들을 xml을 통해 넘겨받았습니다. xml에는 camera, image, shader, surface, light에 관한 정보들이 들어있습니다.
다음은 하나의 구를 저장하는 xml의 예시입니다.
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
|
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Test scene with a single sphere.
-->
<scene>
<camera>
<viewPoint>5 4 3</viewPoint>
<viewDir>-5 -4 -3</viewDir>
<projNormal>5 4 3</projNormal>
<viewUp>0 1 0</viewUp>
<projDistance>5</projDistance>
<viewWidth>2.5</viewWidth>
<viewHeight>2.5</viewHeight>
</camera>
<image>
300 300
</image>
<shader name="blue" type="Phong">
<diffuseColor>.2 .3 .8</diffuseColor>
<specularColor>1 1 0</specularColor>
<exponent>50</exponent>
</shader>
<surface type="Sphere">
<shader ref="blue" />
<!--shader type="ShowNormal"/-->
<center>0 0 0</center>
<radius>1</radius>
</surface>
<light>
<position>3 4 5</position>
<intensity>1 1 1</intensity>
</light>
</scene>
|
cs |
xml parsing을 쉽게 하기 위해 ElementTree를 사용해보았습니다. 우리에게 필요한 객체 중 하나인 camera를 생성해보았습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for c in root.findall('camera'):
if (c.findtext('projNormal')):
if (c.findtext('projDistance')):
view = View(viewPoint, viewDir, viewUp, viewProjNormal, viewWidth, viewHeight, projDistance, intensity)
|
미리 저장 받은 root에서 camera에 관련된 정보를 모두 찾습니다. findall과 findtext를 적절히 사용하여 view 객체를 생성할 수 있습니다. camera와 마찬가지로 surface별로 객체를 생성해주었습니다. surface 객체는 Sphere와 Box 객체로 나누어 list에 한번에 저장해주었습니다. 이 때 주의해주어야 할 점은 shader의 개수와 surface의 개수가 같지 않다는 점 입니다. 다른 surface더라도 shader를 공유할 수 있으니 큰 for문에서 surface를 지정해주고 그 surface에 맞는 shader를 찾아주었습니다. xml안의 ref는 tag를 통해 접근할 수 있습니다. light에 관한 정보도 클래스로 만들어 list로 관리해주었습니다.
사용한 클래스의 형태는 다음과 같습니다. 먼저 색상을 정하기 위한 color class가 있습니다.
1
2
3
4
5
6
7
8
9
10
|
class Color:
def __init__(self, R, G, B):
def gammaCorrect(self, gamma):
inverseGamma = 1.0 / gamma;
def toUINT8(self):
|
gammaCorrection을 제공합니다. 기본값으로 쓰이는 2.2를 나중에 넣어서 이미지를 저장해주었습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class Shader:
def __init__(self, type):
self.t = type
class ShaderPhong(Shader):
def __init__(self, diffuse, specular, exponent):
self.d = diffuse
self.s = specular
self.e = exponent
class ShaderLambertian(Shader):
def __init__(self, diffuse):
self.d = diffuse
|
shader 클래스는 상속을 사용하여 만들어보았습니다. sphere와 box 모두 shader를 갖지만 그 shader가 phong일지 lambertian일지 정해지지 않았습니다. 그래서 상속 구조를 사용하였고, 클래스 내 함수는 따로 존재하지 않습니다.
나머지 클래스들은 모두 기본변수만 갖는 클래스로 구성하였습니다. box 클래스는 parsing 과정에서 미리 normal vector를 구하여 list로 넣어주었습니다. 매번 계산하게되면 속도 지연이 일어나기 때문입니다.
'컴퓨터 그래픽스' 카테고리의 다른 글
[파이썬을 이용한 Ray Tracing 구현] 5. shade와 그림자 생성 (3) | 2019.05.05 |
---|---|
[파이썬을 이용한 Ray Tracing 구현] 4. ray vector 구하기와 intersect 판정 (1) | 2019.05.05 |
[파이썬을 이용한 Ray Tracing 구현] 2. PyCharm 설치하기 (0) | 2019.05.04 |
[파이썬을 이용한 Ray Tracing 구현] 1. Ray Tracing이란? (0) | 2019.05.04 |