120 likes | 268 Views
Light & Texture. 이승섭 c127@dongguk.edu 2006.09.19. 프로그램 순서도. Light. 3 차원의 세계는 본래 빛이 없는 공간이다 . 여기에 광원을 추가함으로써 정점 (vertex) 이 폴리곤으로 보일 수 있는 것이다 . 그러기 위해서는 재질 (D3DMATERIAL9) 과 광원 (D3DLIGHT9) 이 필요하다 . 화면에 아무것도 나타나지 않는 현상이 일어날 경우 그 중 대부분은 카메라를 잘못 설정해서 메시를 보지 않고 엉뚱한 곳을 바라보게 하거나
E N D
Light & Texture 이승섭 c127@dongguk.edu 2006.09.19
Light 3차원의 세계는 본래 빛이 없는 공간이다. 여기에 광원을 추가함으로써 정점(vertex)이 폴리곤으로 보일 수 있는 것이다. 그러기 위해서는 재질(D3DMATERIAL9)과 광원(D3DLIGHT9)이 필요하다. 화면에 아무것도 나타나지 않는 현상이 일어날 경우 그 중 대부분은 카메라를 잘못 설정해서 메시를 보지 않고 엉뚱한 곳을 바라보게 하거나 광원을 설정하지 않고 배경을 검은색으로 지우는 것이다. 이럴 경우 메시는 광원이 없으면 기본이 검은색이기 때문에 배경의 색과 맞물려 화면에 아무것도 보이지 않는다. 우리가 현실에서 보는 물체의 색은 물체가 반사하는 빛의 색에 의해 결정된다. 빨간 공은 빨간 빛 이외의 다른 모든 빛을 흡수하여 빨간색으로 보이는 것이다.
Material 재질은 크게 네가지로 나눌 수 있다 Diffuse - 표면이 반사하는 난반사광의 양을 지정한다. Ambient - 표면이 반사하는 환경광의 양을 지정한다. Specular – 표면이 반사하는 정반사광의 양을 지정한다. Emissive – 이 성분은 전반적인 표면의 컬러를 더하는데 사용되며, 물체 자체가 빛을 발하는 것처럼 좀더 밝은 물체 효과를 만들어낸다. Power – 정반사광의 날카로운 정도(shapness)를 지정하며, 값이 높아질 수록 하이라이트가 강조된다.
Material 예를 들어 빨간 공을 원한다고 가정해보자. 그렇다면 빨간 빛만을 반사하고 다른 모든 빛을 흡수하도록 재질을 설정하면 된다. D3DMATERIAL9 red; ZeroMemory( &red, sizeof(D3DMATERIAL9) ); red.Diffuse = D3DXCOLOR(1.0f,0.0f,0.0f,1.0f); // 빨간색(RGBA) red.Ambient = D3DXCOLOR(1.0f,0.0f,0.0f,1.0f); // 빨간색(RGBA) red.Specular = D3DXCOLOR(1.0f,0.0f,0.0f,1.0f); // 빨간색(RGBA) red.Emissive = D3DXCOLOR(0.0f,0.0f,0.0f,1.0f); // 빛을 발산하지 않음(RGBA) g_pd3dDevice->SetMaterial( &mtrl ); // 재질을 적용한다. 예에서는 G,B 값을 0 으로 지정하여 재질이 두가지 빛을 0% 반사하도록 지정했으며 적색 성분은 1로 지정하여 100% 반사하도록 하였다. 만약 이 예에서 광원이 파란색 빛만을 발산하도록 했다면 파란빛은 모두 흡수하고 반사할 빨간 빛이 없으므로 공의 색상을 제대로 보여줄 수 없을 것이다. 모든 빛을 흡수하는 물체는 검은색,모든 빛을 100% 반사하는 물체는 흰색으로 나타난다.
Light D3D는 다음과 같은 4가지 종류의 광원을 지원한다. 1.Ambient light 2.Point light 3.Directional light 4.Spot light 위의 광원에 대한 설명은 용그림 교재 158p , 해골그림 교재 81p 를 참고한다. 이제 광원을 설치하는 방법에 대해서 알아보자. 다음에 나오는 예제에서는 흰색 방향성 확산광 광원을 설치할 것이다. making white(1.0f,1.0f,1.0f) directional diffuse light. 조명을 설치하기전 다음을 참고한다 http://blog.naver.com/chtmd/110008951696
Light D3DXVECTOR3 vecDir; // 빛의 방향 D3DLIGHT9 light; // 라이트를 사용하기 위한 구조체 선언 ZeroMemory( &light, sizeof(D3DLIGHT9) ); // light 가 가리키는 주소 초기화 light.Type = D3DLIGHT_DIRECTIONAL; // directional 라이트 사용한다. light.Diffuse.r = 1.0f; // diffuse 라이트 (흰색) light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; light.Direction = D3DXVECTOR3(0.0f,1.0f,0.0f ); // 빛의 방향 // D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir ); // 방향벡터는 단위벡터로 나타내기 때문에 정규화(normalize)를 해준다. light.Range = 1000.0f; // 빛이 도달할 수 있는 거리 g_pd3dDevice->SetLight( 0, &light ); // 위까지의 light 설정을 0번 광원으로 설정. g_pd3dDevice->LightEnable( 0, TRUE ); // 0번 광원 켠다 (스위치 라고 생각) g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); // 조명을 켠다.
Summary 이제까지 설정한 재질과 광원을 적용하면 실제로 메쉬에 광원과 그림자가 들어간 것을 확인 할 수 있을 것이다. 이 단원에서 확인하고 넘어가야 할 것은. 재질과 조명의 색을 설정함에 따라 수도 없는 색상의 조합이 가능하다는 것이며. 또한 조명을 설치하기만 하고 켜주지 않는다면 소용이 없다는 것을 알 수 있다. 이 부분(조명,재질)에 관해서는 diffuse 라이트만을 보고 넘어갔지만 나중, 과제라던가 실 제로 게임을 제작하기 위해서는 여러 라이트와 재질을 조합해서 사용해야 한다. Directx 도움말에서 라이트에 관련된 부분을 찾아 개인적으로 공부해보고 소스에 적용해 보는 것을 추천한다.
Texture 텍스쳐를 사용하기 위해서는 다음과 같은 순서를 따른다. 1.IDirect3DTexture9 선언 2. 텍스쳐 좌표를 갖는 정점 선언 3.텍스쳐 생성(일반적으로 파일을 로드하여 생성하지만 라이트 맵핑 등의 기법에서는 텍스쳐를 직접 생성하기도 한다.) 4.텍스쳐 스테이지 설정 5.그려질 텍스쳐 지정 6.메시 그리기
이들이 실제 소스와 어떻게 일대일로 대응하는지 비교해 보자. • LPDIRECT3DTEXTURE9 g_pTexture = NULL; • Struct CUSTOMVERTEX { • D3DXVECTOR3 position; // 3차원 좌표 • D3DCOLOR color; // 색깔 • FLOAT tu,tv; } // 텍스쳐 좌표 #define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) 3. D3DXCreateTextureFromFile(g_pd3dDevice,”banana.bmp”,&g_pTexture) 4. g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); 5. g_pd3dDevice->SetTexture(0,g_pTexture); 6. g_p3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2*50-2);