에서 내 앞의 질문 , 나는 연기 조명 투영 텍스처링을 할 수 있는지 물었다. 이제 (반년 이상) 같은 일을 구현하는 데 문제가 있습니다. 이 기술을 가벼운 패스에 적용하려고합니다. (내 프로젝터는 알베도에 영향을 미치지 않습니다). 이 프로젝터가 있습니다 투사 행렬을 봅니다.
Matrix projection = Matrix.CreateOrthographicOffCenter(-halfWidth * Scale, halfWidth * Scale, -halfHeight * Scale, halfHeight * Scale, 1, 100000);
Matrix view = Matrix.CreateLookAt(Position, Target, Vector3.Up);
여기서 halfWidth
및 halfHeight
IS 감촉의 폭과 높이의 절반이며, Position
프로젝터의 위치이며, target
프로젝터의 대상이다. 이것은 괜찮은 것 같습니다. 이 셰이더로 전체 화면 쿼드를 그립니다.
float4x4 InvViewProjection;
texture2D DepthTexture;
texture2D NormalTexture;
texture2D ProjectorTexture;
float4x4 ProjectorViewProjection;
sampler2D depthSampler = sampler_state {
texture = <DepthTexture>;
minfilter = point;
magfilter = point;
mipfilter = point;
};
sampler2D normalSampler = sampler_state {
texture = <NormalTexture>;
minfilter = point;
magfilter = point;
mipfilter = point;
};
sampler2D projectorSampler = sampler_state {
texture = <ProjectorTexture>;
AddressU = Clamp;
AddressV = Clamp;
};
float viewportWidth;
float viewportHeight;
// Calculate the 2D screen position of a 3D position
float2 postProjToScreen(float4 position) {
float2 screenPos = position.xy / position.w;
return 0.5f * (float2(screenPos.x, -screenPos.y) + 1);
}
// Calculate the size of one half of a pixel, to convert
// between texels and pixels
float2 halfPixel() {
return 0.5f / float2(viewportWidth, viewportHeight);
}
struct VertexShaderInput {
float4 Position : POSITION0;
};
struct VertexShaderOutput {
float4 Position :POSITION0;
float4 PositionCopy : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input) {
VertexShaderOutput output;
output.Position = input.Position;
output.PositionCopy=output.Position;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 {
float2 texCoord =postProjToScreen(input.PositionCopy) + halfPixel();
// Extract the depth for this pixel from the depth map
float4 depth = tex2D(depthSampler, texCoord);
//return float4(depth.r,0,0,1);
// Recreate the position with the UV coordinates and depth value
float4 position;
position.x = texCoord.x * 2 - 1;
position.y = (1 - texCoord.y) * 2 - 1;
position.z = depth.r;
position.w = 1.0f;
// Transform position from screen space to world space
position = mul(position, InvViewProjection);
position.xyz /= position.w;
//compute projection
float3 projection=tex2D(projectorSampler,postProjToScreen(mul(position,ProjectorViewProjection)) + halfPixel());
return float4(projection,1);
}
픽셀 쉐이더의 첫 번째 부분은 G- 버퍼 (이 코드는 다른 셰이더에서 아무 문제없이 사용하고 있음)에서 위치를 복구 한 다음 프로젝터 뷰 프로젝션 공간으로 변환됩니다. 문제는 투영이 나타나지 않는다는 것입니다. 내 상황의 이미지는 다음과 같습니다.
녹색 선은 렌더링 된 프로젝터 절두체입니다. 내 실수는 어디에 숨겨져 있습니까? XNA 4를 사용하고 있습니다. 조언을 주셔서 감사하고 영어를 유감스럽게 생각합니다.
편집하다:
위의 셰이더가 작동하지만 투영이 너무 작습니다. Scale 속성을 큰 값 (예 : 100)으로 변경하면 투영이 나타납니다. 그러나 카메라가 투영쪽으로 이동하면 이 YouTube 비디오 에서 볼 수 있듯이 투영이 확장됩니다 .