1. 버그 현상
- Emissive를 사용할 때 카메라 방향인 정면에서 봤을 때는 제대로 동작하지만, 카메라를 돌려서 측면이나 뒷면을 보게 될 경우에는 제대로 작동하지 않는 현상 발생


2. 원인 찾기
1. 쉐이더
00.Light.fx
- Emissive를 만들어주는 코드에서는 현재 큰 문제가 없다는걸 볼 수 있음
- 원인x
{
float3 E = normalize(cameraPosition - worldPosition);
float value = saturate(dot(E, normal));
float emissive = 1.0f - value;
emissive = smoothstep(0.0f, 1.0f, emissive);
emissive = pow(emissive, 1.f);
emissiveColor = GlobalLight.emissive * Material.emissive * emissive;
}
14.NormalMapping.fx
output.position을 input.position과 W의 곱으로 월드좌표를 변환했지만, output.worldPosition에서 input.position.xyz를 가져왔던 부분을 수정
- 원인x
MeshOutput VS(VertexTetrueNormalTangent input)
{
MeshOutput output;
output.position = mul(input.position, W);
output.worldPosition = output.position.xyz;
output.position = mul(output.position, VP);
output.uv = input.uv;
output.normal = mul(input.normal, (float3x3) W);
output.tangent = mul(input.tangent, (float3x3) W);
return output;
}
00.Global.fx
CameraPosition()함수 float3(-V._41_42_43)에서 V값이 잘못됬다?
- 하지만,
14.NormalMapping.fx에서 output.position = mul(output.position, VP)를 함으로써 잘 들어갔음을 볼 수 있음
- 원인x
RenderManager, Camera
RenderManger에서 PushGlobalData()에서 V가 잘 안들어갔다면, 정상적으로 실행x
Camera에서 UpdateMatrix()부분의 View계산도 제대로 들어가있음
- 원인x
CameraPosition()
- CPU부분이랑 다른 부분에서 문제가 없다는 것은 `
00.Global.fx에서 만들어준 CameraPosition()함수에서의 좌표값이 제대로 전달이 안됬을 확률이 가장 높다.
14.NormalMapping.fx의 PS에서 CameraPosition()을 pos 변수로 받아서 출력해보자
float4 PS(MeshOutput input) : SV_TARGET
{
ComputeNormalMapping(input.normal, input.tangent, input.uv);
float4 color = ComputeLight(input.normal, input.uv, input.worldPosition);
float3 pos = CameraPosition();
return float4(pos.xyz, 1);
}


- 카메라의
Rotation을 이동하게되면 색상이 변경되는 것을 알 수 있음
- View를 구할때 Rotation값을 간과했던 부분이 문제

문제 해결
00.Global.fx
CameraPosition()에서 -V._41_42_43이 아닌 Rotation도 포함이 되어 있는 View의 역행렬VInv._41_42_43으로 구해주자
RenderManger
- View의 역행렬을 쉐이더에서 수정해줄수 있지만, CPU에서 값을 계산해서 GPU로 넘겨주는 방식으로 진행
RenderManager의 GlobalDesc에서 Matrix VInv추가
RenderManager의 PushGlobalData()에서 VInv에 Veiw.Invert()를 대입
float3 CameraPosition()
{
return VInv._41_42_43;
}
struct GlobalDesc
{
Matrix V = Matrix::Identity;
Matrix P = Matrix::Identity;
Matrix VP = Matrix::Identity;
Matrix VInv = Matrix::Identity;
};
void RenderManager::PushGlobalData(const Matrix& view, const Matrix& projection)
{
_globalDesc.V = view;
_globalDesc.P = projection;
_globalDesc.VP = view * projection;
_globalDesc.VInv = view.Invert();
_globalBuffer->CopyData(_globalDesc);
_globalEffectBuffer->SetConstantBuffer(_globalBuffer->GetComPtr().Get());
}


참고 강의
https://www.inflearn.com/courses/lecture?courseId=329791&type=LECTURE&unitId=161137&tab=script&subtitleLanguage=ko