(내 나쁜 영어 죄송합니다.)그림자 매핑 (HLSL, 쉐이더 모델 3.0)
내가 스택 오버플로에 새로 온 사람와 MS 비주얼 C++ 2015 컴파일러와 3D 게임 응용 프로그램을 작성, Direct3D를 9 HLSL (Shader 모델 3.0).
4 개의 렌더링 타겟 텍스처로 지연 렌더링 로직을 구현했습니다. 렌더 타겟 텍스처에 픽셀의 깊이 값을 저장하고 그림자 맵을 만들었습니다. 결과는 다음과 같습니다. (메쉬 카메라에 가까운 작은 크기를 갖기 때문에 모든 메쉬 블랙 컬러를 갖는다. 멀리 평면 거리 값 1000.0f이다.) I 섀도 매핑 쉐이더 출력 그림자 전체 화면 쿼드 렌더링
The depth texture and the shadow map.
붉은 색으로 쉐이더가 올바르게 작동하는지 확인하십시오. 그러나 셰이더가 잘못된 결과를 출력하는 것으로 보입니다. 그림자 맵 텍스처 출력은 메쉬 서페이스에서 반복됩니다. 여기
https://www.youtube.com/watch?v=1URGgoCR6Zc
는 쿼드을 그리는 그림자 매핑 정점 셰이더입니다.struct VsInput {
float4 position : POSITION0;
};
struct VsOutput {
float4 position : POSITION0;
float4 cameraViewRay : TEXCOORD0;
};
float4x4 matInverseCameraViewProjection;
float4 cameraWorldPosition;
float farDistance;
VsOutput vs_main(VsInput input) {
VsOutput output = (VsOutput)0;
output.position = input.position;
output.cameraViewRay = mul(float4(input.position.xy, 1.0f, 1.0f) * farDistance, matInverseCameraViewProjection);
output.cameraViewRay /= output.cameraViewRay.w;
output.cameraViewRay.xyz -= cameraWorldPosition.xyz;
return output;
}
여기에 쿼드를 그릴 섀도우 매핑 픽셀 셰이더가 있습니다.
struct PsInput {
float2 screenPosition : VPOS;
float4 viewRay : TEXCOORD0;
};
struct PsOutput {
float4 color : COLOR0;
};
texture depthMap;
texture shadowMap;
sampler depthMapSampler = sampler_state {
Texture = (depthMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
sampler shadowMapSampler = sampler_state {
Texture = (shadowMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
//float4x4 matCameraView;
float4x4 matLightView;
float4x4 matLightProjection;
float4 cameraWorldPosition;
float4 lightWorldPosition;
float2 halfPixel;
float epsilon;
float farDistance;
PsOutput ps_main(PsInput input) {
PsOutput output = (PsOutput)0;
output.color.a = 1.0f;
//Reconstruct the world position using the view-space linear depth value.
float2 textureUv = input.screenPosition * halfPixel * 2.0f - halfPixel;
float viewDepth = tex2D(depthMapSampler, textureUv).r;
float3 eye = input.viewRay.xyz * viewDepth;
float4 worldPosition = float4((eye + cameraWorldPosition.xyz), 1.0f);
//Test if the reconstructed world position has right coordinate values.
//output.color = mul(worldPosition, matCameraView).z/farDistance;
float4 positionInLightView = mul(worldPosition, matLightView);
float lightDepth = positionInLightView.z/farDistance;
float4 positionInLightProjection = mul(positionInLightView, matLightProjection);
positionInLightProjection /= positionInLightProjection.w;
//If-statement doesn't work???
float condition = positionInLightProjection.x >= -1.0f;
condition *= positionInLightProjection.x <= 1.0f;
condition *= positionInLightProjection.y >= -1.0f;
condition *= positionInLightProjection.y <= 1.0f;
condition *= positionInLightProjection.z >= 0.0f;
condition *= positionInLightProjection.z <= 1.0f;
condition *= positionInLightProjection.w > 0.0f;
float2 shadowMapUv = float2(
positionInLightProjection.x * 0.5f + 0.5f,
-positionInLightProjection.y * 0.5f + 0.5f
);
//If-statement doesn't work???
float condition2 = shadowMapUv.x >= 0.0f;
condition2 *= shadowMapUv.x <= 1.0f;
condition2 *= shadowMapUv.y >= 0.0f;
condition2 *= shadowMapUv.y <= 1.0f;
float viewDepthInShadowMap = tex2D(
shadowMapSampler,
shadowMapUv
).r;
output.color.r = lightDepth > viewDepthInShadowMap + epsilon;
output.color.r *= condition;
output.color.r *= condition2;
return output;
}
그림자 맵의 자외선이 일부 잘못된 값이 보인다,하지만 난 진짜 문제는 무엇을 알아낼 수 없습니다.
도움을 주셔서 감사합니다.
편집 : 쉐이더 코드를 업데이트했습니다. 뷰 공간의 선형 깊이를 사용하기로 결정하고 세계 지위가 올바른 가치를 지니고 있음을 확인했습니다. 섀도우 맵 좌표 값에 잘못된 값이있는 이유를 정말로 이해하지 못합니다 ...
나쁜 영어는 무엇입니까? –