필요한 개념
이전에 했던거 : 결국에는 칼과 충돌체를 어디에다 붙일거냐이거
인스턴싱 문제?
인스턴싱의 슬롯은 사실 1개밖에 사용 못함(셰이더 때문에)
1) 슬롯을 여러개 사용할 수 있도록 세팅
2) 셰이더 컴파일 시간이 오래걸려서(셰이더를 미리 컴파일해서 불러다 쓰는 방식으로 바꿈)
지금 Render/Shader.h는 한파일을 불러서 이미 불러진 Shader라면 다시한번 불르지 않고 복사만하는 방식으로 작성했었다.
이미 로딩되어 있는 셰이더는 따로 로딩을 하지 않고 기존 결과를 사용! 하지만 컴파일을 수행해야하므로 렌더링까지의 시간이 많이 걸린다.
2) .fx라면 기존것을 불러다 씀, .fxo(fx object)라면 컴파일을 하지 않고 그 결과를 읽어서 사용(훨씬더 빨라짐)
fx는 기존 방식대로 컴파일, fxo는 미리 컴파일 해놓은 확장자이다.
1)인스턴싱할때 슬롯을 여러개 사용할 수 있도록
Inst로 시작한다면 인스턴싱 슬롯이며 다음의 숫자는 슬롯 번호가 될 것이다.
한 모델의 그룹이 가지게 되는 매터리얼이므로 모델 전체에 동일하게 적용된다. 각 모델의 값을 바꾸고 싶을 때는 인스턴스에 별도의 정보를 넣어야 한다.
그래서 슬롯을 여러개 사용할 수 있도록 수정했다.
ex)
struct MaterialDesc
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float4 Emissive;
};
ex) 상대 목을 때렸을때 색을 바꾸고 싶다. -> 슬롯을 하나 더 추가해야함
00_Renders
struct VertexMesh
{
float4 Position : Position;
float2 Uv : Uv;
float3 Normal : Normal;
matrix Transform : Inst1_Transform; // 1번
float4 Color : Inst2_Color; // 2번 슬롯의 인스턴싱 정보를 받아옴
};
Renders/shader.cpp를 수정해서 Inst2_Color; 이라면 Inst 다음에 붙는 숫자를 슬롯번호로 지정했다.
슬롯이 더 필요하다면 더 늘리면 됨
2)컴파일 프로그램을 편하게 수행하기 위해 "외부도구"로 등록해 준다.
도구 -> 외부도구
단축키를 설정하면 단축키 누르면 해당 기능을 수행가능
C로 짠 ShaderCompiler.exe -> compileFromFile() 함수를 이용해 만든것
이 .exe를 외부도구로 등록할 것이다.
제목 세팅하고
명령에 해당 exe 경로 넣어준다.
인수는 /F 하면 파일명이 들어가도록 했다.
/F 한칸띄어서 인수 넣기
/F $(ItemDir) $(ItemFileName) $(ItemExt)
항목 디텍터리, 항목 파일 이름, 항목 확장명
이 인수를 받도록 프로그램에 세팅해놨다.
초기 디렉터리 : ../../Shaders(여기에 있는 파일을 하라는 얘기)
출력창 체크 하면 비주얼 스튜디오 에러창에 나온다.
설정하면 도구->설정한 이름이 뜬다.
컴파일하고 싶은 Shader 파일 들어가서
저 메뉴 누르면 됨
-> 컴파일 성공 뜸
Shader 컴파일 단축키 등록을 위해
도구 -> 옵션 -> 환경 -> 키보드
다음 문자열을 포함하는 명령 표시에서 외부 치면 외부 명령이 나온다.
우리가 외부도구 넣었던 리스트 순서대로 나옴
외부명령1,
외부명령2....
이런식
순서 찾아서 거기에 키 할당하면 됨
정리
ex) Inst2_Color
Inst - 접두어
2 - 슬롯번호
_Color - 이름
Shader.h 수정 코드는 따로 올리지 않음
ModelAnimator.h 추가된 내용
class ModelAnimator
{
private:
// 컬러를 여러개 넣음
Color colors[MAX_MODEL_INSTANCE];
VertexBuffer* instanceBuffer2;
}
ModelAnimator.cpp 추가된 내용
ModelAnimator::ModelAnimator(Shader* shader)
: shader(shader)
{
...
for (UINT i = 0; i < MAX_MODEL_INSTANCE; i++)
{
colors[i] = Color(1, 1, 1, 1);
colors[i] = Math::RandomColor3();
colors[i].a = 1.0f;
}
instanceBuffer2 = new VertexBuffer(colors, MAX_MODEL_INSTANCE, sizeof(Color), 2, true);
...
}
void ModelAnimator::Render()
{
...
instanceBuffer2->Render();
}
55_Renders.fx 수정된 내용
...
technique11 T0
{
P_VP(P0, VS_Mesh, PS)
P_VP(P1, VS_Model, PS)
P_VP(P2, VS_Animation, PS_Color)
}
00_Render.fx 수정된 내용
struct VertexMesh
{
// 0번 슬롯
float4 Position : Position;
float2 Uv : Uv;
float3 Normal : Normal;
// 1번 슬롯
// Inst가 붙은 애들을 만든 Shader 클래스에서 1번으로 취급(이후에 설명)
// world 정보가 들어가 있다.
matrix Transform : Inst1_Transform;
float4 Color : Inst2_Color;
};
#define VS_GENERATE \
output.oPosition = input.Position.xyz;\
\
output.Position = WorldPosition(input.Position);\
output.wPosition = output.Position.xyz;\
output.Position = ViewProjection(output.Position);\
\
output.Normal = WorldNormal(input.Normal);\
\
output.Uv = input.Uv;\
output.Color = input.Color;
struct VertexModel
{
float4 Position : Position;
float2 Uv : Uv;
float3 Normal : Normal;
float3 Tangent : Tangent;
float4 BlendIndices : BlendIndices;
float4 BlendWeights : BlendWeights;
uint InstanceID : SV_InstanceID;
// Inst라는 키워드가 반드시 앞에 붙어야 한다.
// matrix Transform : InstTransform; // Instancing
// SV 키워드는 우리가 시스템에 알려주거나, 시스템이 우리에게 데이터를 넘겨줄때
// SV_InstanceID : 얘가 우리에게 Instance id를 리턴해줌(현재 그리는 애의 인스턴스를 알 수 있다.)
matrix Transform : Inst1_Transform;
float4 Color : Inst2_Color;
};
결과
'DirectX11 3D > 기본 문법' 카테고리의 다른 글
<DirectX11 3D> 78 - PointLighting & HLSL FlowControl (0) | 2022.03.09 |
---|---|
<DirectX11 3D> 75 - Lighting(Ambient, Diffuse, Specular, Emissive) (0) | 2022.03.09 |
<DirectX11 3D> 71 - GetMultiBones (0) | 2022.03.09 |
<DirectX11 3D> 70 - Obb Collision(OBB와 OBB 충돌) (0) | 2022.03.02 |
<DirectX11 3D> 69 - OBB Raycast(OBB와 반직선 교차) (0) | 2022.03.02 |