메쉬 셰이더 조명
메쉬 셰이더에 조명연산을 추가해보자
조명연산을 위해 어떤 값들이 필요할까?
빛의 벡터 g_vLightDir;
빛의 디퓨즈,앰비언트,스펙큘러값
메쉬의 재질 g_vMtrlAmbient : 값을 미리 정의하자
메쉬의 스펙큘려 g_vMtrlSpecular : 값을 미리 정의하자
스펙큘러 연산을 위해선 어떤값이 필요할까?
카메라의 위치와 몇번 제곱해줄것인지 Power가 필요하다.
Player의 SetUp_ConstantTable에서 클라이언트에서 셰이더로 값을 전달해주자.
카메라의 위치를 구할때마다 뷰행렬을 가져와서 역행렬을 구해주는것이 번거롭다 -> 파이프라인에 카메라의 위치를 Get함는 함수를 만들자.
게임인스턴스를 통해 호출할수있게 해주자.
마저 카메라의 위치도 셰이더로 전달해주자.
셰이더_메쉬 로 돌아와서
이번엔 픽셀셰이더에서 조명연산을 해보자.
PS_IN에 float4 vNormal을 받아주자(VS에서 월드로 변한한뒤 정규화까지해서 던져주자(빛이 월드포지션이니까)
픽셀셰이더에서 노말벡터와 (정규화하고 뒤집은) 빛의 벡터를 내적해서 명암(fShade)를 구하자.
빛의 반사벡터 vReflect와 vLook을구해주자
vReflect는 reflect함수로 빛의 벡터와 픽셀의 법선벡터를 넘겨주자
vLook 픽셀의 위치에서 카메라의 위치를 뺴야한다. vPosition은 뷰포트상의 좌표이다. PS_IN에 vWorldPos를 받아주자.
뒤집은 반사벡터와 vLook을 내적하고 g_fPower승을 해서 더해주자.
디퓨즈 (명암 + (앰비언트) + (스펙큘러상수) 스펙큘러해서 Out.vColor에 넣어주자
노말맵이 있더라면 무조건 픽셀셰이더에서 연산을 해줘야한다.
노말맵엔 픽셀들의 노말값들이 저장되어있기때문
Mesh_Dynamic
네컨 프로토에서 파일을 불러온다
/* 메시에 포함되어있는 프레임(뼈 : 계층구조 )의 정보를 함께 불러들인다
포함구조 루트프레임(실제뼈의정보긴하지만 아무정보도 가지고있지않음 오로지 다른 뼈의 포인터하나를 가지고있음
D3DXLoadMeshHierarchyFromX(경로,D3DXMESH_MANAGED,장치,얼로게이트하이러라키,유저데이터로더(NULL) 또다른 데이터가있느냐?,LPD3DXFRAME -> 루트프레임(이곳에 담아주겠다,애님컨트롤러(nullptr) )
애니메이션돌리는건 DX에선 굉장히 간단하다. 나중에 사용
하이어라키
하이어라키를 하나 선언하자 ID3DXAllocateHierarchy
이 구조체는 함수의 원형만제공해준다. 멤버함수로 순수가상함수를 가지고있다. 객체화도안됨 -> 자식 클래스를 하나 만들어줘야한다.
메시다이내믹의 로더에 하이어라키 클래스를 만들어주자.
참조수 관리를 위해 CBase도 상속받는다.
두 부모의 순수가상함수들을 받아오자.
STDMETHOD 표준화된 함수라는 매크로이다.
생성자의 인자로 장치를 받아서 보관하자
Create에서 초기화를위한 함수는 딱히필요없다 생성만 해주자.
하이어라키에서 상속받은 함수는 내가 구현하지만 내가 호출하지 않는다 다이렉트가 하이어라키프롬x함수를 호출하면 함수안에서 내가 구현한 함수들을 호출한다(이를 위해 순수가상함수로 선언된것이다.)
이름이나 정보들을 구현된 형태가 다 읽어준다 이를 정리해서 어떻게 넣을것인지를 내가 구현하는것이다.
카메라뼈가있을경우 : 카메라를 넣어야되는경우와 카메라가 뼈를 바라봐야하는 경우 2가지가 있다.
하이어라키::CreateFrame()
메쉬를 로드하면 알아서 호출되는 함수이다.
Name은 input이고 ppNewFrame은 Output이다
뼈를 내가 할당하고 넘겨줘야한다.
왜 할당을 사용자에게 맡겼을까?
D3DXFrame이 입맛에 안맞을수도있으니깐 안맞는경우 새로운 D3DXFrame_Derived등을 만들어서 할당하라고.
예 : CombinedTransfromationMatrix 결합된상태를 의미
부모가 곱해져야하는경우 예 ) 손가락은 부모를 기준으로 상태행렬이 구성되어있다.부모를 안곱하면 원점에 손가락이 그려진다.
이를 위해 행렬을 컴바인드에 누적한다.
애니메이션
버텍스애니메이션 : 정점 하나하나에 애니메이션을 구현한다
프레임애니메이션 : 뼈를 통해 애니메이션을 구현
모든뼈는 행렬이라는 정보를 가지고있다. 행렬을 이용해서 뼈를 움직임.
뼈의 상태변환을 각 정점들에 모두 곱해줌
상태변환을 정점이아니라 뼈에만 해주면되니 훨씬 가벼움
루트프레임의 첫번째의 자식주소는 첫번째 뼈의 주소를 가짐
모든 뼈들을 두개의 다른뼈의 주소를 가지고있음 자식과 형제
형제본 : 하나의 부모로부터 파생된 뼈
자식본 : 자신의 자식 뼈
루트포인터부터형제가있다면 형제를 보고없다면 자식을 본다.