DirectX Graphics 프로그래밍 가이드 프로그래밍 가능한 파이프라인 정점 셰이더 조명을 사용한 텍스처 맵   [목차열람] [주소복사] [슬롯비우기]
조명을 사용한 텍스처 맵
 
Microsoft DirectX 9.0

조명을 사용한 텍스처 맵


이 예에서는, 정점 셰이더를 사용해, 텍스처 맵을 적용해, 장면(scene)에 조명을 추가한다. 사용하는 개체는 구체이다. 샘플 코드는, 지구의 텍스처 맵을 구체에 적용해, 디퓨즈 라이트를 적용해 밤과 낮을 시뮬레이트 한다.

샘플 코드는, Shader3 의 예에의 추가이며, 텍스처를 맵핑 한 개체에 조명을 추가한다. 텍스처 맵의 로드와 텍스처 스테이지 스테이트의 설정에 대해서는, Shader3 를 참조할것.

샘플 코드의 프레임워크(framework)에 대해서는, 「샘플 프레임워크(framework)」로 상세하게 설명한다. 샘플 코드를 샘플 프레임워크(framework)에 컷 앤드 페이스트 하는 것만으로, 동작하는 샘플을 간단하게 생성 할 수 있다.

정점 셰이더의 생성

정점 데이터는, Shader3 샘플로부터, 정점의 법선을 포함하도록(듯이) 변경되고 있다. 조명이 나타나도록(듯이) 하려면 , 개체에 정점의 법선이 필요하다. 정점 데이터의 데이터 구조를 다음에 나타낸다.

struct CUSTOMVERTEX_POS_NORM_COLOR1_TEX1
{
    float       x, y, z;        // position
    float       nx, ny, nz;     // normal
    DWORD       color1;         // diffuse color
    float       tu1, tv1;       // texture coordinates
};

셰이더 선언은, 입력 정점 레지스터와 그것들에 관련된 데이터를 정의한다.

// Create the shader declaration.
D3DVERTEXELEMENT9 decl[] = 
{
	{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
	{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,  0 },
	{ 0, 28, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
	D3DDECL_END()
};

이 선언은, 정점의 위치·법선·디퓨즈색·텍스처 좌표를 포함한 1 스트림의 데이터를 선언한다.

다음에, 셰이더를 생성 한다. 셰이더는, ASCII 텍스트 캐릭터 라인으로부터 생성 하는지, 같은 명령을 저장 한 셰이더 파일로부터 로드한다. 이 예에서는, 셰이더 파일을 사용한다.

// v7  vertex diffuse color used for the light color
// v8  texture 
// c4  view projection matrix
// c12 light direction

vs_1_1                       // version instruction
dcl_position v0              // declare register data
dcl_normal v4                // v0 is position, v4 is normal
dcl_color0 v7                // v7 is diffuse color
dcl_texcoord0 v8             // v8 is texture coordinates
m4x4 oPos, v0, c4            // transform vertices using view projection transform
dp3  r0, v4, c12             // perform lighting N dot L calculation in world
mul  oD0, r0.x , v7          // calculate final pixel color from light intensity and
                             // interpolated diffuse vertex color 
mov  oT0.xy , v8             // copy texture coordinates to output  

최초로 버전 번호를 반드시 지정한다. 마지막 명령은, 텍스처 데이터를 출력 레지스터 oT0 로 이동한다. 셰이더 명령을 기입한 다음에, 그것들을 사용해 셰이더를 생성 할 수 있다.

LPDIRECT3DPIXELSHADER9 m_pVertexShader;
TCHAR        strShaderPath[512];
LPD3DXBUFFER pCode;                  // buffer with the assembled shader code
LPD3DXBUFFER pErrorMsgs;             // buffer with error messages
DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath), 
                        _T("VertexShader3.vsh") );

D3DXAssembleShaderFromFile( strPixelShaderPath, NULL, NULL, 0,  
                            &pCode, &pErrorMsgs, NULL );   
m_pd3dDevice->CreateVertexShader((DWORD*) pCode->GetBufferPointer(),
                                  &m_pVertexShader)
pCode->Release();
pErrorMsgs->Release();

Microsoft® Direct3D® 는, 이 파일을 찾아내면 정점 셰이더를 생성 해 셰이더 개체를 돌려준다. 이 샘플에서는, 셰이더를 생성 하도록(듯이) 수정한 셰이더 파일을 사용한다. 셰이더 명령을 나타내는 ASCII 텍스트 캐릭터 라인을 생성 하는 방법도 있다.

정점 셰이더의 정수

정점 셰이더 정수는, 다음과 같이 셰이더 파일의 밖에서 정의할 수 있다. 여기에서는, 뷰/투영 행렬, 디퓨즈 라이트의 색, RGBA, 및 라이트의 방향 벡터를 셰이더에 건네주기 위해서(때문에), 정수를 사용한다.

float constants[4] = {0, 0.5f, 1.0f, 2.0f};
m_pd3dDevice->SetVertexShaderConstantF( 0, (float*) &constants, 1 );

D3DXMATRIX mat;
D3DXMatrixMultiply( &mat, &m_matView, &m_matProj );
D3DXMatrixTranspose( &mat, &mat );
m_pd3dDevice->SetVertexShaderConstantF( 4, (float*) &mat, 4 );

float color[4] = {1,1,1,1};
m_pd3dDevice->SetVertexShaderConstantF( 8, (float*) &color, 1 );

float lightDir[4] = {-1, 0,1,0}; // fatter slice
m_pd3dDevice->SetVertexShaderConstantF( 12, (float*) &lightDir, 1 );

def 명령을 사용해, 셰이더내에서 정수를 정의할 수도 있다.

렌더링

셰이더 명령을 쓰기, 정점 데이터를 적절한 정점 레지스터에 접속해, 정수를 초기화한 다음에, 출력을 렌더링 해야 한다. 렌더링 코드에서는, 정점 버퍼 데이터 스트림을 검색하는 장소를 Direct3D 에 알려 Direct3D 에 셰이더 핸들을 건네준다. 텍스처를 사용하기 위해(때문에), 텍스처 스테이지를 설정해 텍스처 데이터의 사용법을 Direct3D 에 알릴 필요가 있다.

// Identify the vertex buffer data source.
m_pd3dDevice->SetStreamSource(0, m_pVB,  sizeof(CUSTOMVERTEX_POS_NORM_COLOR1_TEX1));
// Identify the shader.
m_pd3dDevice->SetVertexShader( m_pVertexShader );

// Define the texture stage(s) and set the texture(s) used
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTexture( 0, m_pTexture0 );

// Draw the object.
DWORD dwNumSphereVerts = 2 * m_dwNumSphereRings*(m_dwNumSphereSegments + 1);
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, dwNumSphereVerts - 2);

출력 이미지는 다음과 같이 된다.

렌더링

텍스처 맵을 적용 하면, 구가 지구처럼 보인다. 조명에 의해, 지구의 표면에 명암의 그라데이션이 생긴다.



© 2002 Microsoft Corporation. All rights reserved.
↑TOP