Shader 21.12.01

김주현·2021년 12월 1일

셰이더

목록 보기
6/18

메시

현재 메시를 로드해서 텍스처를 올리지않고 그린상태
아직 셰이더도 사용하지않고 있다.

D3DXLoadMeshFromX함수를 호출함으로써 정점버퍼를 생성 + 인덱스버퍼도 생성

메시의 디퓨즈맵 + 노멀맵 +스펙큘러맵 을 로드한다.

디테일하게 각픽셀의 정보들을 보관하고있다.
디퓨즈맵 노멀맵 스펙큘러맵이있다.
스펙큘러맵은 정해진 형식이없고 회사마다 형식이 다르다.

이름형식을 맞춰주자

TombStone.x를 열면 TextureFileName에 끝에 _D를추가하자(디퓨즈를 의미)(여기서 변경했으면 실제이미지의 이름도 변경해야 불러올수있다.)

m_pMaterials는 재질수만큼 생성된다.
m_pMaterials는를 사용하기 편현타입으로 캐스팅하자
m_pMaterials->GetBuffer

몇개의 재질을 가지고있는지를 m_dwMaterials에 저장했다 이를 인자로 반복문으로

D3DXMATERIAL*로 m_pMaterials->GetBufferPointer캐스팅한후 i만큼 더해주며 인덱스를 넘어가고 pMaterial에 저장해주자.

D3DXMATERIAL구조체에 D3DMATERIAL9안의 디퓨즈값은 그렇게 중요한지 않다 텍스처를 로드해서 입힐것이기때문.

이미지를 어떻게 저장할것인지 형태를 잡자

vector m_Materials에 디퓨즈맵하나만저장한다.

현재 이름이 D인애들만 읽는다 이를 N과 S로 바꾸면서 로드해야한다.

그럼 벡터도 텍스처 세장을 묶어서 가질수있게 MeshMaterialTexture를 선언하고 이를 벡터의 변수로 써주자.

vector m_Materials

다시 로드하는 부분으로 돌아가서
MESHMATERIALTEXTURE를 new로 만들고 ZeroMemory로 초기화해주자.
pMaterial->pTextureFileName으로 이름을 가져온다 근데 char형이다 _tchar pTexturefFileName에 Tchar로 변환해서 넣어주자.
MultiByteToWideCHar()함수는 char을 -> tchar로 변환해준다.
MultiByteToWideCHar(CP_ACP,0,이름,이름길이,저장받을 위치 ,저장받을곳의 길이)

다음 인자로 받은 path에 pTextureFileName을 붙여주자.

D3DXCreateTextureFromFile()로 디퓨즈맵을 로드하자

_D를지우고 N으로 넣고 S로 넣고하는거보단 x파일에 텍스처파일이름 %s로 하고 D,N,S를 넣어주자.

DiffuseFileName을 만들고
wsprintf(szDiffuseFileName,szTextureFileName,L"D");

다음은 N을 넣어서 노멀맵을 로드하고 S를 넣어서 스펙큘러맵을 로드해주자.
파일이 없는경우도있을수있다. return해주지말자.

텍스처로드를 성공했다.
복사생성자에서 m_Materials을 복사해줄때 안에 들어있는것은 모두 Com객체이니 for문을 통해 pMeshMaterialTexture에있는 맵들을 Safe_AddRef()호출해자(맵이없어서 null이더라도 괜찮다).

Free또한 호출해준다.
clone일때만 SafeDelete로 지워주자.

로드한 텍스처를 세팅하자

CMesh_Static의 렌더에서 장치의 Set_Texture를 호출해주자.

셰이더적용

플레이어를 셰이더로 그리도록 변경해주자.

mesh를 그리기위한 셰이더를 만들어주자.
셰이더 Rect를 복제하자.

우선은 디퓨즈맵만 받아와서 사용해보자.

VS_IN에 Normal을 추가해주자.
VS_OUT,PS_IN에 fShade와 fSpecular를 추가해주자

로딩클래스로 가서 만든 Shader_Mesh를 추가해주자.
플레이어에 Shader_Mesh컴포넌트를 추가해주자.

Render()를 수정해주자. 셰이더를 이용해서 그리면 장치에 값을 셋팅하는것은 다 의미가없다.

셰이더에 값을 전달해주던 부분을 Set_UpConstantTable로 빼주자.

SetUp_ConstantTable()

월드,뷰,투영 매트릭스를 넘겨주자.(뷰,투영은 파이프라인을 통해 꺼내와서 전달한다.)

서브셋(재질정보가 같은 플리곤의 집합)마다 텍스쳐가있다.
이미지를 어떻게 전달할것인가.

루프를 엔진이 아닌 클라이언트에서 돌리자.
CMesh_Static의 Render의 인자로 iMaterialIndex를 받아서 해당하는 인덱스의 DrawSubset을 호출해주자.

이를위해선 클라이언트에서 m_dwNumMaterials를 알고있어야한다 Get함수 만들어주자.

플레이어의 Render로 돌아와서

NumMaterials를 받아오고 이를 인자로 for문을 돌리면서 Render를 호출해주자.
하지만 지금 텍스처가 메쉬안에 들어있다.

메쉬에게 Set_TextureOnShader함수를 만들어서 셰이더의 어떤 변수에 던져줘야하는지,어떤 텍스처를 던져야하는지,몇번째 서브셋에서)를 전해주자.
클라에서 받아와서 넘겨주는 방법보단 이것이 깔끔하다

SetUp_TextureOnShader(셰이더,D3DXHANDLE hParameter,텍스처타입,인덱스)

셰이더에 텍스처를 넘겨주자.

switch문으로 eType에따라 m_Materials[iMaterialIndex]에서 Map을꺼내서 pTexture에 저장하자

pShader->SetUp_TextureConstantTable(던질 전역변수명,pTexture)로 텍스처를 셋업해주자.

플레이어의 렌더로 돌아오자.

m_pShaderCom의 비긴과 엔드 를 호출해주자.

현재 디퓨즈맵이 이상하게 들어간다.

Begin한 이후에 텍스처를 주기때문.

값을 던져준후에 Begin해주면되지만 Begin은 프레임드랍이 심하다.

어쩔수없이 Begin이후에 값을 던져줘야 하는 경우 셰이더의 Commit을 호출해주자.

CShader::Commit() { m_pEffect->CommitChanges() }
변경사항을 정리한다.

뚫린부분을 구현해주기위해 Shader_Mesh에서
알파테스트를 켜주자.

Alpharef로 짤리는 값을 조정할수있다.
참고로 알파테스트는 픽셀셰이더 전에 수행된다.

0개의 댓글