'그래픽스 > 해골책' 카테고리의 다른 글
텍스처링, 빌보드, 높이맵을 사용한 지형 생성 (0) | 2021.05.11 |
---|---|
노말 매핑, 시차 매핑(parallax mapping) (0) | 2021.05.11 |
해골책 : 카메라 (0) | 2020.10.26 |
해골책 : 스키닝, 매트릭스 팔레트 (0) | 2020.10.26 |
해골책 : 애니메이션 (0) | 2020.10.26 |
텍스처링, 빌보드, 높이맵을 사용한 지형 생성 (0) | 2021.05.11 |
---|---|
노말 매핑, 시차 매핑(parallax mapping) (0) | 2021.05.11 |
해골책 : 카메라 (0) | 2020.10.26 |
해골책 : 스키닝, 매트릭스 팔레트 (0) | 2020.10.26 |
해골책 : 애니메이션 (0) | 2020.10.26 |
Direct X Utility
제공 기능
- 윈도우 생성
- Direct3D 디바이스 선택
- Direct3D 디바이스 생성
- 디바이스 이벤트 처리
- 윈도우 이벤트 처리
- 창 모드와 전체 화면 모드 사이의 전환
맨 마지막은 좀 소소한 느낌이 드는데, 아무튼
DXUT는 기본적으로 상위 버전의 DX를 우선적으로 지원한다. 무슨 소린가 하면
그리고 각종 GUI를 지원하기 위한 기능도 제공하고, IME 기반의 텍스트 입력, 카메라 조작, 타이머 등도 제공
(IME 기반의 텍스트 입력 : 컴퓨터 자판의 개수보다 더 많은 글자를 쓰는 언어를 입력할 때 특정한 방식의 키보드 입력을 하면 해당되는 글자를 나타내는 시스템 = 한글)
이러한 부가기능은 모듈별로 제공, DXUT 프레임워크와 무관하게 따로 사용가능
이런 식으로 DX 샘플 브라우저에서 인스톨 프로젝트로 예제 프로그램 수준 뿐 아니라 실제 상용게임을 개발하는 것도 가능하다고 한다
? 진짜?
DXUT 초기화는 DXUTInit() 함수에서 시작
DXUT를 사용한 윈도우 생성
DXUTGetHWND() 함수를 사용하면 윈도우 핸들을 얻는다
API로 생성된 윈도우 사용시 DXUTSetWindow() 함수를 사용한다. 미리 생성된 윈도우를 DXUT에서 사용 가능
윈도우 이벤트 처리
DXUT를 사용한 이벤트 처리
DXUTCreateWindow() 함수를 사용해 메시지 처리가 가능하다
대부분의 중요한 메시지들은 DXUT에서 자동으로 처리된다.
DXUT가 처리하는 것 외에 추가로 처리를 원한다면 DXUTSetCallbackMsgProg( MsgProc ) 함수를 사용해 메시지 처리 콜백함수 등록 가능
*pbNoFurtherProcessing = true 일 경우 사용자가 메시지 처리를 완료한 것으로 인식,
DXUT가 그 메시지에 대해 추가적 처리를 하지 않게 함. 그러나 DXUT 오작동 가능성이 있으니 사용 시 주의
윈도우를 직접 생성했다면 메시지 처리도 직접 하는 것이 가능
DXUTStaticWndProc() 함수로 관련 메시지를 DXUT에 넘겨서 처리할 수 있다.
래스터라이저 (0) | 2020.11.29 |
---|---|
D3DXVec3의 Coord와 Norm (0) | 2020.10.26 |
가우시안 블러 (0) | 2020.09.30 |
드로우 콜 (0) | 2020.09.16 |
Height Map (0) | 2020.09.13 |
환경매핑
카메라 -> 주전자 방향의 벡터는 주전자의 법선벡터와 연산으로 반사벡터를 얻을 수 있다.
reflectionVec = reflect(카메라->주전자 벡터, 주전자 법선벡터);
반사벡터를 구하는 공식은 reflectionVec = p - 2(n(n · p))
p는 입사벡터 n은 노말벡터
슬라이딩벡터는 sVec = p - n(n · p)
환경매핑은 반사벡터가 향하는 지점의 큐브맵에서 X, Y 좌표에 위치한 RGB색상값을 반사벡터의 시점 좌표의 픽셀에 대응시키는것
방법은 texCUBE 함수를 사용하는것
resultColor = texCUBE(큐브맵, 반사벡터);
이다.
여기서 문제가 되는 점이 있다. y축 방향이 0.8이 나오는데, 사실 uv 좌표는
위에서 아래로 내려간다. 아래에서 위로 가는게 아니라...
연산한 y값을 뒤집으면 제대로 된 값이 나오는 것 같은데, 이건 좀 더 알아봐야겠다.
큐브맵 좌표계 검색
https://www.slideshare.net/Mark_Kilgard/11texture
uv 좌표가 아니다...!
스카이박스
카메라를 중심으로 한 큐브나, 스피어 모델을 만들고 거기에 환경맵의 텍스처 매핑을 하는 연산이다.
정점 셰이더에서 할 일은 박스 모델의 중심 위치를 항상 카메라의 위치와 동일하게끔 행렬 연산을 해주는 것이 전부다.
픽셀 셰이더에서 할 일은 정점의 좌표를 받아와서 값을 리턴해주는게 전부다.
렌더스테이트를 잘 설정해야 하는게 스카이박스의 주요 포인트라고 생각된다.
주의 -
스카이박스는 모니터 해상도만큼 픽셀 셰이더를 호출하는 나름 비용 드는 연산이다.
최적화를 위한다면 스카이박스 연산이 필요한 부분을 제외하고는 연산하지 않는 방법이 좋다.
그래서 스카이박스 패스를 맨 마지막으로 미뤄서 진행하라는 말도 있고 뭐, 그렇다
PASS a - 스카이박스
여기서 position3D는 투영공간의 좌표인데, texCUBE 함수는 월드 공간의 연산이다.
좀 더 정확히 하려면 월드 공간의 좌표를 넘겨줘야 하는듯 하다
texCUBE는 월드 공간 값으로 연산해줘야 한다!
PASS b - 환경매핑
코드는 생략
근데 이거 색이 좀 이상하다
포스트 프로세싱이란 장면을 2D 텍스처에 그린 다음, 그 위에 영상처리 기법을 입히는 것이다.
포스트 프로세싱을 이용하면 쓸데없이 셰이더의 수를 늘리는 것을 막을 수 있다.
화면 가득 픽셀을 그리려면 화면을 가득 채우는 사각형을 그린다.
10. 그림자 매핑 (0) | 2020.07.23 |
---|---|
9. UV 애니메이션 & 울렁효과 (0) | 2020.07.22 |
8. 환경매핑 (0) | 2020.07.22 |
7. 노말매핑 (0) | 2020.07.21 |
6. 툰셰이더 (0) | 2020.07.17 |
IDirect3DDevice9::CreateVertexBuffer
정점 버퍼를 생성한다.
Length - [in] 버퍼에 할당할 바이트 수, 8개의 정점을 보관하고 싶다면 8 * sizeof(struct vertex)로 크기를 조정한다.
정점버퍼의 크기, (ex) 한 정점에 들어가는 바이트 수가 들어 있는 변수 offset에 4를 곱하면 정점 4개에 필요한 메모리 크기가 된다.
Usage - [in] 버퍼가 이용되는 방법을 결정하는 특성을 지정
FVF - [in] 정점 버퍼에 보관될 FVF
Pool - [in] 정점 버퍼가 저장될 메모리의 위치(그래픽 카드, 시스템 메모리)와 관리방식 지정
ppVertexBuffer - [out, return value] 반환된 정점 버퍼를 받을 포인터
pHandle - [in] 사용 안한다, 항상 NULL로 설정한다
생성된 정점 버퍼는 쓰레기 값으로 가득 차있다. 정점 버퍼에 값을 넣어주어야 하는데 정점 버퍼의 주소값이 필요하다.
이 때 Lock() 함수로 해당 메모리의 주소를 얻어야 한다.
주의 : 정점 버퍼의 해제는 D3D 디바이스 해제 이전에 이루어져야 한다. 정점 버퍼는 D3D 디바이스를 통해 생성되었기 때문이다
IDirect3DVertexBuffer9::Lock
정점 데이터의 범위를 잠그어, 정점 버퍼 메모리의 포인터를 얻어온다.
(쓰레드의 Lock()을 생각하면 된다. 다른 자원에선 접근이 불가능하다)
이후 획득한 메모리 포인터에 선언한 정점을 memcpy()로 복사한다.
다 끝난 이후엔 Unlock()으로 버퍼 잠금을 해제한다
gpgstudy.com/forum/viewtopic.php?t=5173
IDirect3DDevice9::CreateVertexBuffer
인덱스 버퍼를 생성한다
sizeof(short) * 6 : 인덱스 버퍼의 크기(바이트 수), 16비트 인덱스를 6개 사용하겠다
0 : 특별한 용도로 사용하는건 아니다
D3DFMT_INDEX16 : 각 색인은 16비트이다
D3DPOOL_MANAGED : D3D가 알아서 관리해주는 메모리 풀을 사용하겠다
gpFullscreenQuadIB : 새로 생성된 인덱스 버퍼를 저장할 포인터
NULL : 반드시 NULL이어야 한다
Direct X - 정점 선언 (0) | 2020.09.16 |
---|---|
Direct X 9 - 셰이더(Effect) (0) | 2020.09.16 |
Direct X 9 - 함수 (0) | 2020.09.15 |
구조체
D3DVERTEXELEMENT9
파이프라인의 입력 정점 데이터를 정의한다.
Declaration과 관련된 구조체로, D3DVERTEXELEMENT9 구조체는 각 정보들의 타입이나 데이터의 길이 등을 설정한다.
Stream - 복수의 스트림을 구별하기 위한 번호
D3D 장치에 정점버퍼들을 동시에 여러 개 집어넣어줄 수 있는데, 이 때 정점버퍼가 들어가는 슬롯의 인덱스 번호이다. 정점버퍼가 하나면 0으로 설정하면 된다.
Offset - 스트림으로 사용하는 구조체의 선두 위치로부터 바이트 수
정점정보가 시작하는 메모리 위치에서 현재 요소가 시작하는 곳까지의 오프셋 값. 정점버퍼의 제일 앞에 위치 값을 넣는다면 오프셋은 0이다.
Type - D3DDECLTYPE 의 데이터형을 지정
데이터형이다. 사용하는 데이터에 맞는 형을 설정하면 된다
Method - 테셀레이터가 어느 데이터를 평면 분할에 사용하는지에 대한 선언, 하지 않는다면 D3DDECLMETHOD_DEFAULT
김포프 책에서 DEFAULT 이외 다른 값 사용하는 경우 아직 못봤다고 한다.
Usage - D3DDECLUSAGE 매크로를 사용하여 설정
해당 데이터 요소의 용도를 정의한다. 위치면 위치, 노말이면 노말, 탄젠트면 탄젠트, 텍스처 좌표면 텍스처 좌표 등
UsageIndex - 1개의 셰이더에 복수의 좌표가 있을 때 이를 구별하기 위한 용도로 사용, 셰이더 프로그래밍에서 dcl_positionX 인덱스에 대응
셰이더에서 TEXCOORD 시맨틱을 사용할 때 뒤에 붙던 숫자들(TEXCOORD0, TEXCOORD1, etc)이 UsageIndex이다.
0, 3 * 4, 6 * 4, 8 * 4
float 3개 3개 2개
셰이더를 사용할 때에는 FVF보다 정점선언을 사용하는게 일반적이다. 정점선언은 FVF에서 지원하지 않는 TANGENT나, BINORMAL같은 형도 지원할 뿐 아니라 FVF에서 특정 순서로 정점정보를 넣어줘야만 하는 제약도 없다.
김포프 셰이더 책에서는 정점 선언을 이렇게 처리한다
이러한 방식이 아래와 같은 방식보다는 보기에 편해보이나?
FVF가 좀 더 간편하게 버텍스를 정의해주는 거라면, 정점선언은 좀 더 세세하게 직접 만드는 용도라고 볼 수 있다.
IDirect3DDevice9::CreateVertexDeclaration
장치 및 정점 요소로부터 정점 셰이더 선언을 생성한다
D3DVERTEXELEMENT로 만들어진 배열을 in 인자에 넣고, out 인자로 얻은 IDirect3DVertexDeclaration9** 정점 선언 포인터는, 나중에 메시를 그릴 때 이 정점버퍼의 포맷은 이러이러하니 알아서 올바른 데이터를 뽑아갈 것 이라는 지시를 D3D에 내리는데 사용한다.
IDirect3DDevice9::SetVertexDeclaration
정점 셰이더 선언을 설정한다
SetVertexDeclaration은 vertex의 정보 값을 나타낸다.
Vertex의 속성을 SetVertexDeclaration으로 설정해놓으면, 디바이스는 버텍스 정보를 받아와 정점 입력 레지스터로 받아온다.
Direct X - 버텍스, 인덱스 버퍼 (0) | 2020.09.16 |
---|---|
Direct X 9 - 셰이더(Effect) (0) | 2020.09.16 |
Direct X 9 - 함수 (0) | 2020.09.15 |