Dalam pertanyaan saya sebelumnya , saya bertanya apakah mungkin melakukan textive proyektif dengan pencahayaan yang ditangguhkan. Sekarang (lebih dari setengah tahun kemudian) saya punya masalah dengan implementasi saya dari hal yang sama. Saya mencoba menerapkan teknik ini dalam light pass. (proyektor saya tidak mempengaruhi Albedo). Saya punya proyektor ini. Lihat matriks Proyeksi:
Matrix projection = Matrix.CreateOrthographicOffCenter(-halfWidth * Scale, halfWidth * Scale, -halfHeight * Scale, halfHeight * Scale, 1, 100000);
Matrix view = Matrix.CreateLookAt(Position, Target, Vector3.Up);
Di mana halfWidth
dan mana halfHeight
adalah setengah dari lebar dan tinggi tekstur, Position
adalah posisi Proyektor dan target
merupakan target proyektor. Ini sepertinya ok. Saya menggambar quad layar penuh dengan shader ini:
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);
}
Pada bagian pertama pixel shader dipulihkan posisi dari G-buffer (kode ini saya gunakan di shader lain tanpa masalah) dan kemudian diubah ke ruang proyeksi tampilan proyektor. Masalahnya adalah bahwa proyeksi tidak muncul. Ini gambar situasi saya:
Garis hijau adalah frustrasi proyektor yang diberikan. Di mana kesalahan saya disembunyikan? Saya menggunakan XNA 4. Terima kasih atas sarannya dan maaf untuk bahasa Inggris saya.
EDIT:
Shader di atas berfungsi tetapi proyeksi terlalu kecil. Ketika saya mengubah properti Scale ke nilai besar (mis. 100), proyeksi muncul. Tetapi ketika kamera bergerak ke arah proyeksi, proyeksi mengembang, seperti yang dapat dilihat pada video YouTube ini .
sumber