DirectX Graphics 프로그래밍 가이드 고도의 주제 프레임 버퍼 포그(안개:fog)의 종류 정점 포그(안개:fog) [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
시스템은 정점 포그(안개:fog)를 실행 할 때 다각형의 각 정점에 포그(안개:fog) 계산을 적용해, 다음에, rasterize때, 다각형의 면에 결과를 보간 한다. 정점 포그(안개:fog)의 이펙트는, Microsoft® Direct3D® 의 조명 & 변환 엔진에 의해 계산된다. 더 자세한 정보는, 「포그(안개:fog) 파라미터」를 참조할것.
애플리케이션으로 Direct3D 를 사용하지 않고 변환 & 조명을 실행하는 경우는, 애플리케이션으로 포그(안개:fog) 계산을 실시할 필요가 있다. 이 경우, 계산된 포그(안개:fog) 계수를, 각 정점의 스펙큐러색의 알파 성분에 둔다. 공식으로는, 범위 베이스의 공식, 체적을 이용하는 공식적인 , 어떠한 것에서도 사용할 수 있다. Direct3D 는 주어진 포그(안개:fog) 계수를 사용해, 각 다각형의 면을 보간 한다. 애플리케이션으로 독자적인 변환 & 조명을 실행하는 경우는, 독자적인 정점 포그(안개:fog)의 계산을 실행할 필요가 있다. 따라서, 그러한 애플리케이션에서는, 「포그(안개:fog) 혼합」 및 「포그(안개:fog)색」으로 설명하도록(듯이), 포그(안개:fog) 혼합을 유효하게 해, 관련하는 렌더링 스테이트에 의해 포그(안개:fog)색을 설정하는 것만으로 좋다.
포그(안개:fog)를 사용하면 개체가 포그(안개:fog)색과 직감적이 아닌 방법으로 블렌드 되는 부자연스러운 그래픽스 효과가 생기는 일이 있다. 예를 들어, 2 개의 개체가 보이고 있어, 한편은 포그(안개:fog)의 영향을 받을 정도로에 멀리 있어, 한편은 영향을 받지 않을 정도 에 근처에 있다고 하는 장면(scene)를 상정한다. 표시 영역이 같은 장소에서 회전했을 경우, 개체가 정지하고 있었다고 해도, 나타나는 포그(안개:fog) 이펙트는 변화하는 일이 있다. 다음 그림은 이러한 상황을 위로부터 보았더니 있다.
범위 베이스의 포그(안개:fog)는, 포그(안개:fog) 이펙트를 보다 정확하게 결정하는 방법이다. 범위 베이스의 포그(안개:fog)에서는, Direct3D 는 시점으로부터 정점까지의 실제의 거리를 포그(안개:fog)의 계산에 사용한다. 장면(scene)의 범위내에서의 정점의 깊이는 아니고 2 점간의 거리의 증가에 따라 포그(안개:fog)의 이펙트가 증가되기 (위해)때문에, 부자연스러운 회전 효과가 회피된다.
현재의 장치가 범위 베이스의 포그(안개:fog)를 지원 하고 있는 경우,IDirect3DDevice9::GetDeviceCaps 메서드를 호출했을 때에, 장치는 D3DCAPS9 의 RasterCaps 멤버에 D3DPRASTERCAPS_FOGRANGE 값을 설정한다. 범위 베이스의 포그(안개:fog)를 유효하게 하려면 ,D3DRS_RANGEFOGENABLE 렌더링 스테이트를 TRUE 로 설정한다.
범위 베이스의 포그(안개:fog)는, Direct3D 에 의해, 변환 & 조명의 사이에 계산된다. Direct3D 변환 & 조명 엔진을 사용하지 않는 애플리케이션은, 독자적으로 정점 포그(안개:fog)의 계산도 실시해야 한다. 이 경우, 범위 베이스의 포그(안개:fog) 계수를, 각 정점의 스펙큐러 성분의 알파 성분으로 설정한다.
애플리케이션으로 정점 포그(안개:fog)를 유효하게 하려면 , 다음의 순서를 실행한다.
다음의 C++ 샘플 코드는, 이러한 순서를 나타내고 있다.
// For brevity, error values in this example are not checked // after each call. A real-world application should check // these values appropriately. // // For the purposes of this example, g_pDevice is a valid // pointer to an IDirect3DDevice9 interface. void SetupVertexFog(DWORD Color, DWORD Mode, BOOL UseRange, FLOAT Density) { float Start = 0.5f, // Linear fog distances End = 0.8f; // Enable fog blending. g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE); // Set the fog color. g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color); // Set fog parameters. if(D3DFOG_LINEAR == Mode) { g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode); g_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start)); g_pDevice->SetRenderState(D3DRS_FOGEND, *(DWORD *)(&End)); } else { g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode); g_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density)); } // Enable range-based fog if desired (only supported for // vertex fog). For this example, it is assumed that UseRange // is set to a nonzero value only if the driver exposes the // D3DPRASTERCAPS_FOGRANGE capability. // Note: This is slightly more performance intensive // than non-range-based fog. if(UseRange) g_pDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE); }
IDirect3DDevice9::SetRenderState 메서드는, 제 2 인수에 DWORD 값만을 받지만, 부동 소수점의 포그(안개:fog) 파라미터가 요구되는 일도 있다. 이 예에서는, 부동 소수점의 값을 데이터의 평행이동없이 메서드에 건네주기 위해서(때문에), 부동 소수점 변수의 주소를 DWORD 포인터로서 캐스트 해, 다음에 그것을 참조로부터 해제하고 있다.