728x90

FOV는 카메라의 시야각을 의미한다. 

기본적으로 FOV 수치가 높으면 시야각은 넓어지고 사물은 멀리 있는 것 처럼 보인다.

반대로 FOV 수치가 낮으면 시야각은 좁아지고 사물은 가까이 있는 것 처럼 보인다.

 

다음의 두 스크린 샷을 통해 확인해보자.


 

                              FOV : 100                                                              FOV : 80

 

같은 위치의 카메라 시야각에 따라 다양하게 보인다.

또한 FOV의 수치가 커질수록 왜곡의 정도도 심해진다. (카메라의 광각렌즈)

 

이런 다양함을 가지고 각 장르의 게임마다 FOV를 다르게 가져간다.

 

가령 1인칭 게임의 대표인 FPS 장르는 FOV를 40이하로 하는 것이 보통이다.

정면을 주시하며 정확한 타겟팅이 필요한 게임에서 왜곡이 심하고 좌우 시야가 넓은 높은 시야각은 불필요하다. (스나이퍼가 줌을 당기는 것은 그 순간 FOV 수치를 매우 낮게 변경한 것이다.)

 

TPS 장르의 경우에는 FOV가 40 ~ 70 정도이다.

TPS는 3인칭 장르로 캐릭ㅌ너의 액션이 추가된다. 때문에 캐릭터의 모든 액션들을 카메라에 담기 위해서는 다소 높은 시야각을 요구한다. 캐릭터가 좌, 우로 빠르게 이동하는 과정에서 FOV가 낮다면 휙휙 지나가게 되어 어지러움을 느끼게 된다.

(기어워는 55기준으로 상황에 따라 바뀌는 것으로 알고 있다.)

 

RPG는 넓은 필드가 있기 때문에 시야각이 넓다.

 

마지막으로 FOV(시야각)에 따른 표현의 차이를 정리해본다.

 

1. 낮은 FOV

 - 카메라에 보이는 좌우폭이 좁다.

 - 상대적으로 사물이 가까워 보인다. (거리감이 작게 느껴진다.)

 - 왜곡이 적다.

 - 정면으로 이동시 속도감이 떨어진다.

 

2. 높은 FOV

 - 카메라에 보이는 좌우폭이 넓다.

 - 상대적으로 사물이 멀어보인다. (거리감이 크게 느껴진다.)

 - 왜곡이 많다. (엔진에 따라 차이가 있지만, 100이상에서 확실히 느껴진다.)

 - 정면으로 이동시 속도감이 많다.



출처 : http://cafe.naver.com/comeonqa.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=79&

728x90
728x90

D3D11_TEXTURE2D_DESC 구조체

2차원 텍스처에 대한 정보를 서술하는 구조체

 

 멤버 변수

 설명 

 Width

 2차원 텍스처의 가로 크기 ( 텍셀 단위 )

 Height

 2차원 텍스처의 세로 크기 ( 텍셀 단위 )

 MipLevels

 최대 밉맵 레벨

 다중 샘플링 텍스처는 1을 사용하며 0을 사용하면 가능한 최대 밉맵 레벨을 설정한다.

 ArraySize

 텍스처 배열의 텍스처 개수

 Format

 텍스처의 텍셀 데이터 형식

 SampleDesc

 다중 샘플링 정보를 나타내는 구조체

 Usage

 텍스처를 어떻게 읽고 쓸 것인지를 나타내는 D3D11_USAGE 열거형 상수

 보통 D3D11_USAGE_DEFAULT 를 사용한다

 BindFlags

 텍스처를 파이프라인 단계에 어떻게 연결할 것인가를 나타내는 D3D11_BIND_FLAG 열거형 상수

 CPUAccessFlags

 허용되는 CPU 접근 권한을 나타내는 D3D11_CPU_ACCESS_FLAG 열거형 상수

 0을 사용하면 CPU가 이 텍스처에 접근할 필요가 없다는 의미

 MiscFlags

 D3D11_RESOURCE_MISC_FLAG 열거형 상수

 보통 0을 사용한다.

 


ID3D11Device::CreateTexture2D() 함수

2차원 텍스처 리소스를 생성하는 함수

2차원 텍스처 리소스는 여러 개의 2차원 서브 리소스를 포함 할 수 있다.

서브 리소스의 개수는 D3D11_TEXTURE2D_DESC 구조체에서 설정 가능하며 하나의 리소스에 있는 모든 텍스처의 크기, 데이터 형식, 밉맵 레벨은 같아야 한다.



 매개 변수

 설명 

 pDesc

 D3D11_TEXTURE2D_DESC 구조체에 대한 포인터

 pInitailData

 서브 리소스를 서술하는 D3D11_SUBRESOURCE_DATA 구조체에 대한 배열

 텍스처를 텍셀 데이터로 초기화하기 위해서는 이 구조체로 텍스처 데이터를 지정해야 한다.

 NULL을 지정하면 서브 리소스를 나중에 지정하겠다는 의미이다.

 텍스처가 D3D11_USAGE_IMMUTABLE을 사용하여 생성하였다면 이 값에 NULL을 사용할 수 없다.

 다중 샘플링되는 리소스는 생성 중에 초기화할 수 없기 때문에 이 값은 반드시 NULL이 되어야 한다.

 ppTexture2D

 생성된 텍스처에 대한 인터페이스에 대한 포인터

 이 값을 NULL로 설정하면 입력 매개 변수의 유효성을 검사할 수 있다. 이 경우 S_FALSE가 반환되면 유효하다는 의미이다

 


D3D11_SUBRESOURCE_DATA 구조체

리소스의 서브 리소스를 초기화하는 구조체

 

 멤버 변수

 설명 

 pSysMem

 초기화 데이터에 대한 포인터

 SysMemPitch

 텍스처의 특정 줄의 시작에서 다음 줄의 시작까지의 바이트 수

 이 값은 2차원, 3차원 텍스처 데이터를 초기화할 때 사용하고 다른 리소스에서는 의미가 없다.

 SysMemSlicePitch

 특정 깊이 레벨의 시작에서 다음 깊이 레벨까지의 바이트 수

 이 값은 3차원 텍스처를 초기화할 때 사용하고 다른 리소스에서는 의미가 없다.

 


D3DX11CreateTextureFromFile() 함수

파일로부터 텍스처 리소스를 생성하기 위한 함수

 

 매개 변수

 설명 

 pDevice

 디바이스 인터페이스에 대한 포인터

 pSrcFile

 파일의 이름

 pLoadInfo

 파일에서 텍스처 데이터를 어떻게 읽을 것인가를 지정하는 D3DX11_IMAGE_LOAD_INFO 구조체

 이 구조체를 설정하면 내용에 맞게 텍스처를 로드하며 NULL을 설정하면 텍스처 파일에서 텍스처 데이터의 특성을 읽어서 로드한다.

 pPump

 스레드 펌프 인터페이스 ( ID3DX11ThreadPump)에 대한 포인터

 스레드 펌프는 어떤 작업을 비동기적으로 수행하기 위해 사용된다.

 스레드 펌프를 설정하면 텍스처 파일을 읽기 위해 이 함수가 별도의 스레드를 통해 비동기적으로 수행된다.

 NULL을 지정하면 동기적으로 실행된다.

 스레드 펌프는 D3DX11CreateThreadPump() 함수로 생성한다.

 ppTexture

 생성된 텍스처 리소스( ID3D11Resource )에 대한 포인터의 수조

 pHResult

 함수 반환값을 저장할 변수의 주소

 스레드 펌프를 사용하지 않으면 NULL을 지정한다. 

 스레드 펌프를 사용하면 이 메모리 주소는 함수 호출이 비동기적으로 완료될 때까지 유효해야 한다

 


D3DX11CreateShaderResourceViewFromFile() 함수

파일로부터 쉐이더 리소스 뷰를 생성하기 위해 사용된다.

 


 

 매개 변수

 설명 

 pDevice

 디바이스 인터페이스에 대한 포인터

 pSrcFile

 파일의 이름

 pLoadInfo 

 파일에서 텍스처 데이터를 어떻게 읽을 것인가를 지정하는 D3DX11_IMAGE_LOAD_INFO 구조체

 이 구조체를 설정하면 내용에 맞게 텍스처를 로드하며 NULL을 설정하면 텍스처 파일에서 텍스처 데이터의 특성을 읽어서 로드한다

 pPump

 스레드 펌프 인터페이스 ( ID3DX11ThreadPump)에 대한 포인터

 스레드 펌프는 어떤 작업을 비동기적으로 수행하기 위해 사용된다.

 스레드 펌프를 설정하면 텍스처 파일을 읽기 위해 이 함수가 별도의 스레드를 통해 비동기적으로 수행된다.

 NULL을 지정하면 동기적으로 실행된다.

 스레드 펌프는 D3DX11CreateThreadPump() 함수로 생성한다.

 ppShaderResourceView

 쉐이더 리소스 뷰 인터페이스 ( ID3D11ShaderResourceView )에 대한 포인터의 주소

 pHResult

 함수 반환값을 저장할 변수의 주소

 스레드 펌프를 사용하지 않으면 NULL을 지정한다. 

 스레드 펌프를 사용하면 이 메모리 주소는 함수 호출이 비동기적으로 완료될 때까지 유효해야 한다

 


D3DX11_IMAGE_LOAD_INFO 구조체

파일에서 텍스처를 로드하는 함수가 텍스처를 어떻게 로드할 것인가를 설정하기 위해 사용되는 구조체

 

 멤버 변수

 설명 

 Width

 생성할 텍스처의 가로 크기

 파일에서 로드할 텍스처의 가로 크기가 이 값보다 크거나 작으면 텍스처의 크기가 이 값에 맞도록 변환된다.

 Height

 생성할 텍스처의 세로 크기

 파일에서 로드할 텍스처의 세로 크기가 이 값보다 크거나 작으면 텍스처의 크기가 이 값에 맞도록 변환된다.

 Depth

 텍스처의 깊이

 볼륨 텍스처에만 적용된다

 FirstMipLevel

 텍스처의 가장 큰 해상도의 밉맵 레벨

 이 값이 0보다 크면 텍스처가 로드된 후에 FirstMipLevel은 밉맵 레벨 0으로 매핑된다.

 MipLevels

 텍스처의 최대 밉맵 레벨 

 0 또는 D3DX11_DEFAULT 을 지정하면 최대 밉맵을 가진 텍스처가 생성된다.

 Usage

 텍스처 리소스에 적용될 D3D11_USAGE 열거형 상수

 BindFlags

 텍스처 리소스에 적용될 D3D11_BIND_FLAG 열거형 상수

 CPUAccessFlags

 이 텍스처에 대한 CPU 접근 권한을 나타내는 D3D11CPU_ACCESS_FLAG 열거형 상수

 D3D11_CPU_ACCESS_WRITE 또는 D3D11_CPU_ACCESS_READ를 사용한다.

 가능하면 CPU가 이 텍스처에 접근할 수 없도록 0을 사용한다.

 MiscFlags

 텍스처 리소스에 대한 추가적인 특성을 설정하는 D3D11_RESOURCE_MISC_FLAG 열거형 상수

 Format

 텍스처의 데이터 형식을 나타내는 DXGI_FORMAT 열거형 상수

 Filter

 텍스처에 적용할 필터를 지정하기 위한 D3DX11_FILTER_FLAG 열거형 상수

 MipFilter

 텍스처 밉맵에 적용할 필터를 지정하기 위한 D3DX11_FILTER_FLAG 열거형 상수

 D3D11_FILTER_NONE, D3DX11_FILTER_POINT, D3DX11_FILTER_LINEAR, D3DX11_FILTER_TRIANGLE 을 사용할 수 있다

 pSrcInfo

 원래 이미지에 대한 정보를 나타내는 D3DX11_IMAGE_INFO 구조체

 D3DX11GetImageInfoFromFIle(), D3DX11GetImageInfoFromMemory(), D3DX11GetImageInfoFromResource() 함수 중 하나를 사용하여 D3DX11_IMAGE_INFO 구조체의 정보를 얻는다.

 

D3DX11_IMAGE_LOAD_INFO 구조체는 사용하지 않을 멤버 변수는 설정하지 않는다. 또한 ZeroMemory 함수를 사용하지 않는다.


ID3D11DeviceContext::UpdateSubresource() 함수

CPU가 시스템 메모리의 내용을 맵핑할 수 없는 메모리에 생성된 리소스로 복사한다.


 

 매개 변수

 설명 

 pDstResource

 복사할 목표 리소스에 대한 포인터

 리소스가 D3D11_USAGE_IMMUTABLE, 깊이/스텐실 버퍼, 다중 샘플링으로 생성되었다면 목표 리소스를 사용할 수 없다.

 DstSburesource

 목표 서브 리소스를 나타내는 인덱스

 인덱스는 D3D11CalcSubresource() 함수를 사용하여 계산한다.

 pDstBox

 목표 서브 리소스의 일부분을 나타내는 박스에 대한 포인터

 좌표 단위는 버퍼에는 바이트를 사용하고 텍스처에는 텍셀을 사용한다.

 이 값이 NULL이면 데이터를 목표 서브 리소스에 그대로 복사한다.

 소스의 크기는 목표의 크기와 같아야 한다.

 쉐이더 상수 버퍼의 일부분만 바꾸는 것은 허용되지 않아 쉐이더 상수 버퍼에는 이 값을 NULL로 설정한다

 pSrcData

 복사할 데이터를 나타내는 시스템 메모리의 포인터

 SrcRowPitch

 복사할 데이터의 한 줄의 바이트 크기

 SrcDepthPitch

 복사할 데이터의 깊이 슬라이스 하나의 크기

 


D3D11CalcSubresource() 멤버 함수

텍스처의 서브 리소스 인덱스를 계산하기 위해 사용된다.

버퍼는 구조화되지 않은 리소스이므로 서브 리소스가 하나이다. 따라서 버퍼에 대해서는 이 함수를 사용하지 않는다.

텍스처는 구조화된 리소스이다. 텍스처는 텍스처 배열의 크기와 밉맵 레벨의 개수를 따라 하나 이상의 서브 리소스를 가진다.

 

 매개 변수

 설명 

 MipSlice

 밉맵 레벨의 배열의 인덱스

 0은 첫 번째 밉맵 레벨을 나타낸다.

 ArraySlice

 텍스처의 배열에서 사용할 첫 번째 텍스처의 인덱스 

 MipLevels 

 사용할 밉맵 레벨의 개수

 


리소스의 제약

리소스는 제약이 존재한다.

 리소스

 제약 

 상수 버퍼의 원소 개수

 4096개 

 하나의 버퍼에서 텍셀의 개수

 227텍셀 

 Texture1D U 차원

 8192 

 Texture1DArray 차원

 512 배열 슬라이스 

 Texture2D U/V 차원

 8192 

 Texture2DArray 차원

 512 배열 슬라이스 

 Texture3D U/V/W 차원

 2048 

 TextureCube 차원

 8192 

 리소스 크기

 128MB 

 이방성(Anisotropic) 필터링(Maxanisotropy)

 16

 하드웨어에서 주소로 참조할 수 있는 리소스 차원

 차원마다 8192 

 IA 또는 VS/GS/PS 리소스 크기

 128MB 

 컨텍스트 하나의 리소스 뷰의 최대 개수

 220 

 버퍼 구조체의 크기

 2048 바이트 

 스트림 출력의 크기 

 227 텍셀 

 Draw() / DrawInstanced() 정점 카운트 (인스턴싱 포함 )

 232 

 DrawIndextd[Instanced])( ) 정점 카운트 ( 인스턴싱 포함 )

 232 

 GS 호출 출력 데이터( 요소의 개수 * 정점의 개수 )

 1024 

 컨텍스트 하나의 샘플러 객체의 전체 개수

 4096 

 파이프라인의 뷰 포트/시저 객체의 전체 개수

 16 

 정점마다 Clip/Cull 거리의 전체 개수

 8 

 컨텍스트마다 블렌드 객체의 전체 개수

 4096 

 컨텍스트마다 깊이/스텐실 객체의 전체 개수

 4096 

 컨텍스트마다 래스터라이저 상태 객체의 전체 개수

 4096 

 다중 샘플링 동안 픽셀당 최대 샘플 수

 32 

 쉐이더 리소스 정점의 원소 수 ( 4개의 32비트 요소 )

 16 

 정점 쉐이더에서 입력 레지스터 개수(4개의 32비트 요소)

 16 

 정점 쉐이더에서 출력 레지스터 개수(4개의 32비트 요소)

 16 

 기하 쉐이더에서 입력 레지스터 개수(4개의 32비트 요소)

 16 

 기하 쉐이더에서 출력 레지스터 개수(4개의 32비트 요소)

 32 

 픽셀 쉐이더에서 입력 레지스터 개수(4개의 32비트 요소)

 32 

 픽셀 쉐이더에서 출력 레지스터 개수(4개의 32비트 요소)

 8 

 픽셀 쉐이더에서 출력 깊이 레지스터 개수(1개의 32비트 요소)

 1 

 입력 조립기에서 인덱스 입력 리소스 슬롯의 개수

 1 

 입력 조립기에서 정점 입력 리소스 슬롯의 개수

 16 



출처 : http://blog.naver.com/ram1029123/220419267617

728x90
728x90

1. 렌더링 파이프라인


렌더링 파이프라인이란, 3D 그래픽을 어떻게 그려나가는지에 대한 절차의 설명입니다. 





가. 정점 데이터. 


3D 그래픽이 그려지기 시작하면, 우선 정점 (vertex) 부터 일정한 위치에 그려지게 됩니다. 
그 정점에는 순서를 나타내는 번호가 씌여져 있어서, 각 점을 순서대로 연결하여 면을 만들게 됩니다. 



나. 삼각형 분할


각 vertex를 연결해서 삼각형을 그리게 됩니다. 이 때 시계방향으로 그리냐 시계 반대방향으로 그리냐에 따라 앞 뒷면이 정해지게 되고, 혹은 양 면을 다 그릴 수도 있습니다. 이것은 렌더링 기본설정에서 정해지게 됩니다.  



   



다. 정점 쉐이더 (vertex shader) 

정점 쉐이더에서는 기본적으로 행렬연산에 의한 변환작업이 주로 이루어집니다. 

변환작업이란 다음과 같은 개념이지요. 엄밀하게 말하면 아래 그림과는 조금 다른 개념이지만, 따로 설명하기가 어렵군요.






기본적으로 오브젝트는 자기 자신이 가지고 있는 각각의 좌표계로 되어 있습니다. 






일단 그걸 월드 좌표계로 변환해줍니다. (행렬을 곱해서 만듭니다.) 





다시 그걸 카메라좌표계로 전환을 합니다. 
그걸 카메라에서 바라보면 이런 느낌이 됩니다. 
이것을 Orthographic 또는 Isometric 이라 부릅니다. 
(원근감이 없는 2D 게임 같은 이미지가 됩니다.)








이것에 다시 투영행열을 계산하여 원근감을 구현해 줍니다. 

즉 원근감이 없는 2D 게임같은 이미지는 한 번 더 계산이 줄기 때문에 조금더 빠른 방식이라는 것을 알 수 있습니다. 



이상의 4가지 단계가 일반적인 vertex shading의 기본 단계입니다. 

이후 이 단계에서 Normal 값과 Light Direction, View Direction 등을 이용하여 빛을 계산 할 수도 있습니다. 



2. Clipping


오브젝트 중 화면에 보이지 않는 부분을 잘라서 안 그려버리는 방법입니다. 

당연하게도 보이지 않는 것은 그리지 않는 것이 유리합니다. 



3. Backface Culling

카메라에서 보이지 않는 방향의 면은 그리지 않습니다. 반대방향은 어차피 그려도 보이지 않으니까요. 



이 이외에도 사실 여러 종류의 culling 등이 존재하고 있습니다 .



4. Rasterizing 

이것은 본격적으로 모니터라고 하는 2차원의 어느 부분'픽셀'에 찍힐 것인지를 결정하는 것입니다. 
3차원 이미지는 필연적으로 2차원의 평면인 '모니터' 에 찍혀져야 하기 때문에 다시 2차원의 점으로 환산하는 작업이 필요하게 됩니다. 이것을 Rasterzation 이라고 합니다. 


http://commons.wikimedia.org/wik...n_bw.svg

5.  PixelShader

이 단계에서 픽셀쉐이더가 시작됩니다. 
이 부분에서 하는 일은 Resterizing이 결정되어 찍힐 픽셀이 결정된 상태에서 쉐이딩 - 빛 계산 - 을 시작하게 되는 것으로, 보다 정밀한 계산이 가능해 집니다. 
또한 이 부분에서 텍스쳐 셈플러를 통해 텍스쳐가 입혀지게 됩니다. 

6.  Alpha Test / Alpha blending 
알파 테스트와 알파 블렌딩은 무척 중요한 개념입니다. 
여기에서 sorting의 개념이 같이 들어가기 때문이지요. 
이전에도 설명했듯이, 텍스쳐에는 알파 채널이 들어갈 수 있습니다. 
그 알파 채널은 보통 256 단계로 부드럽게 들어갈 수 있습니다만, 그런 경우 문제가 생길 수 있습니다. 
예를 들어 반투명의 유리창이 있고 그 뒤에 공이 있다면, 공은 유리창 뒤에 있음에도 불구하고 '유리창에 반쯤 영향받은 채 보여야'
할 것입니다. 즉 '뒤에 있는데도 보여져야 한다' 라는 명제가 생기게 되는 것이므로, '뒤에 있으면 그리지 않는다' 라는 기본 깊이테스트를 무시해야 하는 것이지요. 

그렇지만 알파 테스트를 적용하게 하면, 256단계의 부드러운 알파 채널의 단계 중 일정 부분을 정해서 그 투명도를 0 또는 1로 정의해 버립니다. 즉 '반투명' 이란 것은 없고, 이 픽셀이 보이는가 안보이는가만 임의대로 (예를 들어 100보다 크다던가) 결정해 버리는 것입니다. 이렇게 하면 일반 오브젝트 그리는 것과 별 차이 없이 처리할 수 있는 장점이 있지만 알파 채널의 퀄리티는 다소 떨어지게 됩니다. 하지만 대부분의 게임에서는 이 알파 테스트를 사용하게 됩니다 .(다시 말해서, 이전시간에 설명했던 것과 같이 DDS 데이터를 아무리 RGBA 4:4:4:8 로 한다 하더라도 결국 4:4:4:1과 같이 출력되게 되는 것이므로 쓸 데없이 알파 채널을 8비트로 그릴 필요가 없다는 것입니다) 

알파 블렌딩은 이보다 더 복잡하게 됩니다. 위에 설명했던 것 처럼 알파 블렌딩이 들어가게 되면, '모든 픽셀은 언제나 보일 수 있다' 라는 정의가 작동하게 됩니다. 반투명의 유리가 수 십장 겹쳐져 있어도 전부 보이는 것처럼 말입니다. 
그렇게 되면 더 이상Z 버퍼에 의한 거리 판별은 무의미하게 되며, 모든 픽셀은 이 픽셀이 보인다는 가정하에 얼마나 보이는가를 계산해야 되는 상황이 됩니다. 불투명한 오브젝트라 하더라도 일단 계산에는 무조건 올라가게 됩니다. 그러면서도 깊이 테스트는 필요해 질 수 밖에 없는 것이, 중간에 불투명한 오브젝트가 끼어 있을지도 모르기 때문입니다. 불투명한 오브젝트라면 그 뒤의 것들은 그려지지 말아야 하니까요. 이렇게 복잡한 계산 때문에, 제대로 sorting 하지 않으면 아래 그림처럼 나타나게 됩니다. 

그러므로 알파 블렌딩이 사용되게 되면, 나머지 것들을 다 그리고 난 후 알파 블렌딩이 되는 것들만 모아서 위치값을 재 정렬하고, 다시 그것들을 찍으면서 모든 픽셀의 색상을 계산해 줘야 합니다. (얼마나 반투명 되는지 말이지요) 
당연하게도 이것은 엄청난 시간을 들이게 되는 작업이므로, 현재의 게임에서는 되도록 피해야 하는 방법입니다. 



이것은 주로 머리카락 등에서 그래픽 디자이너의 요청으로 사용되어지도록 요청될 수 있습니다. 부드러운 머리카락을 Alpha test 따위로 거칠게 만들어 버리고 싶은 그래픽 디자이너는 없으니까요. 그렇지만 그렇게 되면 역시 오른쪽과 같은 sorting 문제가 발생하면서 다시 그래픽 디자이너의 원망을 듣게 될 것입니다. 
때문에 기술적으로 이해가 높은 그래픽 디자이너가 있는 프로젝트에서는, 머리카락에 알파 블렌딩을 거의 사용하지 않고 처리해 버리기도 합니다. 직접 몇 덩어리씩 모델링 해버리거나, 알파 테스트를 사용하되 해상도를 높여서 지저분한 흔적을 최대한 줄여버리는 꼼수를 사용할 수도 있는 것입니다. 

그렇지만 알파 블렌딩을 아예 사용하지 않을 수는 없습니다. 대표적인 것은 이펙트입니다. 이펙트는 사실상 90% 이상이 알파 블렌딩만으로 처리되며, 높은 수준의 이펙트가 부하를 유발하는 주범이 되는 것은 이 때문입니다. 
또한 반투명한 유리나 비치는 옷 같은 경우도 알파 블렌딩을 사용할 수 밖에 없는 부분입니다. 

그러므로 효율적인 알파 블렌딩을 사용하기 위해서는 '아예 과감히' 사용하는 것이 가장 좋습니다. 
예를 들어 원피스의 옷 한벌에 텍스쳐를 한 장 사용하고,  가슴팍 부분 일부만 반투명으로 하느니 차라리 원피스 전체를 반투명으로 하는 것이 나을 것입니다. (아니면 반투명을 전혀 안쓰도록 디자인하던가 말입니다) 

이것은 Anti-aliasing과도 혼동될 수 있습니다만, 이것은 텍스쳐의 alpha 부분의 정밀도를 계산하는 방법이므로 antialiasing과는 근본적으로 차이가 있음을 주의하시기 바랍니다.

7.Z test 
어느 오브젝트가 앞에 있는지를 판별하는 것입니다. 기본적으로 Z 버퍼(깊이 버퍼)를 이용하여 멀고 가까운 거리를 판별합니다. 
하지만 정밀도가 무한하지 않기 때문에 너무 근접한 오브젝트의 경우에는 오류가 있을 수도 있습니다.

8. 스텐실 테스트 
반사 되는 장면을 그릴 때 거울 부분에만 그려지는 것 처럼 일부분에만 그려지도록 마스킹하는 테스트입니다. 

9. Fog
일정 깊이값을 대상으로 안개의 색상을 더합니다. 
편법으로, 절대 갈 수 없는 원경을 저급한 퀄리티의 폴리곤으로 멀리 만들어 놓고, fog 색의 2*2 의 텍스쳐를 입혀 놓는 편법을 사용하여 게임의 최적화를 하기도 합니다. 




출처 : http://egloos.zum.com/chulin28ho/v/5241665

728x90
728x90

피사계심도란?

W

Depth OField 라고도 하며 


렌즈로 일정 거리에 피사체의 초점을 맞추면 앞면과 뒷면의 일정한 거리 내에 초점이 맞는데

이때 그 범위를 이르는 말로

게임 내에서는 씬 내에 있는 가장 멀리 있는 오브젝트와 가장 가까이 있는 오브젝트 사이의 거리 

즉,카메라에 초점이 맞는 거리 범위를 말한다



크라이시스2 Bokeh 합성 DOF 영상



DOF OFF


DOF ON


DOF OFF


DOF ON


피사체가 초점에 앞에 있으면 렌즈에서 모아진 초점이 렌더타겟에서 보여지는 위치보다
안쪽이 되어 버리므로 감광되는 영역이 넓어지며




피사체가 안쪽에 있으면 렌더타겟에서 보여지는 위치보다 앞쪽에 초점이 위치하게 되므로
한번 모인 빛이 다시 퍼져서 렌더 타겟에 그려진다 ( 마찬가지로 감광되는 영역이 넓어짐)


.
초점이 맞춰져있는 부분은 선명한 화면을.. 나머지 초점이 맞지않는 부분은 블러를 적용하여 흐리게 한다



먼저 일반 화면을 렌더링하고 화면으로부터의 거리를 깊이값으로 렌더링한다.
다음, 렌더링 화면으로부터 뭉갠화면을 생성하고
마지막으로 렌더링한 깊이 값의 정보로부터 초점이 맞는 부분은 선명한 화면
초점이 맞지 않는 위치에는 뭉개진 화면을 합성한다



마지막에 최종 화면을 합성할때 에는 선형보간으로 이루어진다

 return lerp(OriginalImage, BlurredImage, saturate(Range *abs(Focus - PixelCameraZ)));


DOF구현의 기본은 카메라 공간 내에 있는 뭉개진화면인 Far 평면과 Near 평면과의 비교를 할수 있도록
카메라 공간에 그려질 픽셀의깊이값을 변환하는 것이다.

아래는 NDC 공간을 카메라 공간의 좌표로 변환하는데 사용하는 왼손좌표계용 프로젝션 매트릭스이다




아래의 방정식은 위에 투영행렬에 세번째 열에 있는 4D 동차 벡터를 곱한결과를 보여주고 있다




24.2는 매트릭스 w = z일경우 w에 의해 동차적으로 나누어진 최종 깊이 버퍼 방정식이며, 
이를 Z에 대해 풀면 카메라 공간으로 깊이 버퍼 값을 다시 역 변환하는데 사용할수 있다(24.3)

또한, 카메라 공간상의 픽셀의 거리는 깊이 버퍼를 가져오는 대신
씬이 렌더링 되는 동안 카메라 공간상의 각 픽셀에 깊이 값을
렌더 타겟의 알파 채널에 저장할 수 있다

 VS_OUTPUT VS(VS_INPUT Input)

{
    .....

    // 색성분에 깊이값을 넣음

    // 조명계산 필요시, 깊이값을  색성분의 w값에만 사용하고 다른성분에 조명을 계산한값을 출력 
    Out.Color = pos.z / pos.w;

    .....

    return Out;
}

float4 PS(VS_OUTPUT Input) : COLOR0
{
    float4 Out;
    .....

    // 알파 성분에 깊이값 저장
    Out.a = Input.Color.w;

    .....

    return Out;
}


다음  축소 버퍼를 사용해 뭉갠 화면을 준비한 후 초점이 될 깊이값을 어플리케이션에서 세팅한다


이후 강도를 조절하고 lerp()함수를 사용해 선명한 화면과 뭉개진 화면을 합성한다.


 // 카메라 공간으로 역변환

float PixelCameraZ = (-NearClip * Q) / (Depth - Q);


사용자정의 Focus 값과 Range 값은 원래 이미지와 뭉갠이미지 사이를 선형 보간하기 위하여 구한

픽셀의 카메라 거리와 함께 사용되며 최종 화면으로 합성된다


 // 선형 보간

return lerp(OriginalImage, BlurredImage, saturate(Range * abs(Focus - PixelCameraZ)));


이때 절대값을 취하는 이유는 피사계심도가 초점이 맞는 위치를 기준으로 앞쪽과 뒤쪽 모두에서

흐리게 뭉개져야 하므로 초점이 맞는 위치를 기준으로 어느족으로 깊이값이 증가하더라도

뭉개지는 양이 증가 할수 있도록 한것이다

(절대값이 아닌 제곱 값을 취해도 되나 출력상태가 약간 틀리므로 보고 나서 선택 하도록)


이 밖에 Bokeh 합성이 있으며 자세한건 위키피디아를 참조..



NDC11 "올바른 HDR을 이용한 Bloom과 DOF"  이창희님




                 1. 원본이미지                   2. Bokeh 합성                  3. 가우시안 블러 적용 DOF

위키피디아 링크 : http://en.wikipedia.org/wiki/Bokeh

이외에 스타크래프트 2는 CoC Map (Circle of Confusion)을 사용한다고 했다


스타2의 DOF


그림에서 보면 블러를 먹일 양을 결정하진 텍스처 인것 같다

.. 최대치의 블러를 먹일 부분과 초점이 맞는

부분의 사이의 Fade 효과가 들어가는 것일지도... 

대충 봤을때는 현재 픽셀의 블러를 먹일 것인가에 대한 데이터를 가진 텍스쳐인거 같다




출처 : http://blog.naver.com/sorkelf/40149186261


728x90
728x90


728x90
728x90

NVIDIA 그래픽 카드에서만 CUDA가 동작을 한다.


DirectX11을 초기화하는 단계에서 그래픽 카드 정보를 확인하고, NVIDIA 그래픽 카드가 아닌 경우 경고를 띄우기 위해서 


DXGI_ADAPTER_DESC 구조체를 사용하여 확인하였다.



<소스 코드>


CComPtr<IDXGIFactory1> factory = nullptr;

HR(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory));


if (FAILED(factory->EnumAdapters1(m_nAdapterID, &m_pAdapter)))

    return E_FAIL;    // 그래픽 카드가 없기 때문에 종료


DXGI_ADAPTER_DESC desc;

m_pAdapter->GetDesc(&desc);




위와 같이 그래픽 카드의 정보를 가져와서 확인하면 된다.



728x90
728x90

DirectX11을 이용한 Application을 개발하는 도중에 이상한 현상을 발견하였다.


이 현상은 NVidia 계열의 그래픽 카드에서는 발생하지 않고, AMD 계열의 그래픽 카드에서만 발생하였다.


이 현상은 Application 내에서 Device 및 Context 등의 자원들을 계속 생성 및 해제 하다가 DirectX 함수에서 빠져나오지 


못하고 계속 멈춰있는 현상이다.


며칠 테스트를 해본 결과...


CreateBlendState() 함수를 사용할 때 ID3D11BlendState 변수를 생성하고, 해제를 하지 않거나,


CreateSamplerState() 함수를 사용할 때 ID3D11SamplerState 변수를 생성하고, 해제를 하지 않거나,


CreateRasterizerState() 함수를 사용할 때 ID3D11RasterizerState 변수를 생성하고, 해제를 하지 않거나,


등등의 다양한 경우가 있을 것이다.


뭐든 이러한 변수들을 해제하지 않으면서, ID3D11Device등의 리소스를 생성 및 해제를 반복하게 되면, DirectX 함수에서 빠져나오지 못한다.



ps. 생성한 것은 반드시 해제하도록 하자...

728x90
728x90

DirectX SDK 를 설치하지 않고 Windows를 설치할 때 같이 설치된 라이브러리들로 작업을 하려면 기존의 내용을 조금씩 변경을 해야한다.


나의 경우 DXTrace()를 잘 쓰고 있었는데, 이것은 따로 넣어주어야 한다.

DxErr.zip


Shader를 읽기 위해서 사용하는 D3DX11CompileFromFile() -> D3DCompileFromFile() 로 변경되었다.

이 함수를 사용하기 위해서는 헤더와 라이브러리를 추가해야한다.

#include <d3dcompiler.h>

#pragma comment(lib, "d3dcompiler.lib")


구조체 D3DXVECTOR -> DirectX::XMFLOAT 으로 변경되었다. (뒤에 숫자는... 생략)

이 구조체를 사용하기 위해서는 헤더만 추가하면 된다.

#include <DirectXMath.h>

#include <DirectXPackedVector.h>

using namespace DirectX; <- 를 사용해도 무관하지만.... 이전의 회사 프로젝트에서 namespace가 꼬여서 고생한적이 있기 때문에 나는 그냥 namespace를 앞에 붙여서 사용한다. 


함수 D3DX11CreateShaderResourceViewFromMemory() -> CreateWICTextureFromMemory() 로 변경되었다.

dds, tga를 제외한 이미지 파일을 불러올 땐 위의 함수를 사용하면 된다.

#include "WICTextureLoader.h" 를 추가할 것.


이것의 경우 기본적으로 라이브러리가 없기 때문에 https://directxtex.codeplex.com/ 에서 받아서 빌드후 사용하면 되지만, 나는 이미 빌드해서 썻으니까 따로 올린다.

DirectXTex-master.zip




728x90

+ Recent posts